blob: d34756a169b28973d7bb11a26370c4316c16b78b [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
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000894 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000895#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,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000921 PyLong_FromLongLong((PY_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,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000927 PyLong_FromLongLong((PY_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,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000936 PyLong_FromLongLong((PY_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
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002379 return Py_BuildValue("L", (PY_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
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002520 res = Py_BuildValue("L", (PY_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
Neal Norwitzb59798b2003-03-21 01:43:31 +00002575/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002576/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2577#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002578#define DEV_PTY_FILE "/dev/ptc"
2579#define HAVE_DEV_PTMX
2580#else
2581#define DEV_PTY_FILE "/dev/ptmx"
2582#endif
2583
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002584#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002585#ifdef HAVE_PTY_H
2586#include <pty.h>
2587#else
2588#ifdef HAVE_LIBUTIL_H
2589#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002590#endif /* HAVE_LIBUTIL_H */
2591#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002592#ifdef HAVE_STROPTS_H
2593#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002594#endif
2595#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002596
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002597#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002598PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002599"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002600Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002601
2602static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002603posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002604{
2605 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002606#ifndef HAVE_OPENPTY
2607 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002608#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002609#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002610 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002611#ifdef sun
2612 extern char *ptsname();
2613#endif
2614#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002615
Thomas Wouters70c21a12000-07-14 14:28:33 +00002616#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002617 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2618 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002619#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002620 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2621 if (slave_name == NULL)
2622 return posix_error();
2623
2624 slave_fd = open(slave_name, O_RDWR);
2625 if (slave_fd < 0)
2626 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002627#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002628 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002629 if (master_fd < 0)
2630 return posix_error();
2631 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002632 /* change permission of slave */
2633 if (grantpt(master_fd) < 0) {
2634 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002635 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002636 }
2637 /* unlock slave */
2638 if (unlockpt(master_fd) < 0) {
2639 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002640 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002641 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002642 signal(SIGCHLD, sig_saved);
2643 slave_name = ptsname(master_fd); /* get name of slave */
2644 if (slave_name == NULL)
2645 return posix_error();
2646 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2647 if (slave_fd < 0)
2648 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002649#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002650 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2651 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002652#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002653 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002654#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002655#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002656#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002657
Fred Drake8cef4cf2000-06-28 16:40:38 +00002658 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002659
Fred Drake8cef4cf2000-06-28 16:40:38 +00002660}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002661#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002662
2663#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002664PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002665"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002666Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2667Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002668To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002669
2670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002671posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002672{
2673 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002674
Fred Drake8cef4cf2000-06-28 16:40:38 +00002675 pid = forkpty(&master_fd, NULL, NULL, NULL);
2676 if (pid == -1)
2677 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002678 if (pid == 0)
2679 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002680 return Py_BuildValue("(ii)", pid, master_fd);
2681}
2682#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Guido van Rossumad0ee831995-03-01 10:34:45 +00002684#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002685PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002686"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002687Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002688
Barry Warsaw53699e91996-12-10 23:23:01 +00002689static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002690posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002691{
Barry Warsaw53699e91996-12-10 23:23:01 +00002692 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002693}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002694#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Guido van Rossumad0ee831995-03-01 10:34:45 +00002697#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002699"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002701
Barry Warsaw53699e91996-12-10 23:23:01 +00002702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002703posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002704{
Barry Warsaw53699e91996-12-10 23:23:01 +00002705 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002706}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002707#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Guido van Rossumad0ee831995-03-01 10:34:45 +00002710#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002711PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002712"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002713Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002714
Barry Warsaw53699e91996-12-10 23:23:01 +00002715static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002716posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002717{
Barry Warsaw53699e91996-12-10 23:23:01 +00002718 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002719}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002720#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002721
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002722
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002723PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002724"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002726
Barry Warsaw53699e91996-12-10 23:23:01 +00002727static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002728posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002729{
Barry Warsaw53699e91996-12-10 23:23:01 +00002730 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002731}
2732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002733
Fred Drakec9680921999-12-13 16:37:25 +00002734#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002735PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002736"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002738
2739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002740posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002741{
2742 PyObject *result = NULL;
2743
Fred Drakec9680921999-12-13 16:37:25 +00002744#ifdef NGROUPS_MAX
2745#define MAX_GROUPS NGROUPS_MAX
2746#else
2747 /* defined to be 16 on Solaris7, so this should be a small number */
2748#define MAX_GROUPS 64
2749#endif
2750 gid_t grouplist[MAX_GROUPS];
2751 int n;
2752
2753 n = getgroups(MAX_GROUPS, grouplist);
2754 if (n < 0)
2755 posix_error();
2756 else {
2757 result = PyList_New(n);
2758 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002759 int i;
2760 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002761 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002762 if (o == NULL) {
2763 Py_DECREF(result);
2764 result = NULL;
2765 break;
2766 }
2767 PyList_SET_ITEM(result, i, o);
2768 }
2769 }
2770 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002771
Fred Drakec9680921999-12-13 16:37:25 +00002772 return result;
2773}
2774#endif
2775
Martin v. Löwis606edc12002-06-13 21:09:11 +00002776#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002777PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002778"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002779Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002780
2781static PyObject *
2782posix_getpgid(PyObject *self, PyObject *args)
2783{
2784 int pid, pgid;
2785 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2786 return NULL;
2787 pgid = getpgid(pid);
2788 if (pgid < 0)
2789 return posix_error();
2790 return PyInt_FromLong((long)pgid);
2791}
2792#endif /* HAVE_GETPGID */
2793
2794
Guido van Rossumb6775db1994-08-01 11:34:53 +00002795#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002796PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002797"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002799
Barry Warsaw53699e91996-12-10 23:23:01 +00002800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002801posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002802{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002803#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002804 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002805#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002806 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002807#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002808}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002809#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002811
Guido van Rossumb6775db1994-08-01 11:34:53 +00002812#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002814"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Barry Warsaw53699e91996-12-10 23:23:01 +00002817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002818posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002819{
Guido van Rossum64933891994-10-20 21:56:42 +00002820#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002821 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002822#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002823 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002824#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002825 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002826 Py_INCREF(Py_None);
2827 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002828}
2829
Guido van Rossumb6775db1994-08-01 11:34:53 +00002830#endif /* HAVE_SETPGRP */
2831
Guido van Rossumad0ee831995-03-01 10:34:45 +00002832#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002833PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002834"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002835Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Barry Warsaw53699e91996-12-10 23:23:01 +00002837static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002838posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002839{
Barry Warsaw53699e91996-12-10 23:23:01 +00002840 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002841}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002842#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002843
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002844
Fred Drake12c6e2d1999-12-14 21:25:03 +00002845#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002847"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002849
2850static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002851posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002852{
Neal Norwitze241ce82003-02-17 18:17:05 +00002853 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002854 char *name;
2855 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002856
Fred Drakea30680b2000-12-06 21:24:28 +00002857 errno = 0;
2858 name = getlogin();
2859 if (name == NULL) {
2860 if (errno)
2861 posix_error();
2862 else
2863 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002864 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002865 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002866 else
2867 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002868 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002869
Fred Drake12c6e2d1999-12-14 21:25:03 +00002870 return result;
2871}
2872#endif
2873
Guido van Rossumad0ee831995-03-01 10:34:45 +00002874#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002880posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002881{
Barry Warsaw53699e91996-12-10 23:23:01 +00002882 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002883}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002884#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002886
Guido van Rossumad0ee831995-03-01 10:34:45 +00002887#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002888PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002889"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002890Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002891
Barry Warsaw53699e91996-12-10 23:23:01 +00002892static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002893posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002894{
2895 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002896 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002897 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002898#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002899 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2900 APIRET rc;
2901 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002902 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002903
2904 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2905 APIRET rc;
2906 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002907 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002908
2909 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002910 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002911#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002912 if (kill(pid, sig) == -1)
2913 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002914#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002915 Py_INCREF(Py_None);
2916 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002917}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002918#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002919
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002920#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002921PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002922"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002924
2925static PyObject *
2926posix_killpg(PyObject *self, PyObject *args)
2927{
2928 int pgid, sig;
2929 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2930 return NULL;
2931 if (killpg(pgid, sig) == -1)
2932 return posix_error();
2933 Py_INCREF(Py_None);
2934 return Py_None;
2935}
2936#endif
2937
Guido van Rossumc0125471996-06-28 18:55:32 +00002938#ifdef HAVE_PLOCK
2939
2940#ifdef HAVE_SYS_LOCK_H
2941#include <sys/lock.h>
2942#endif
2943
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002944PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002945"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Barry Warsaw53699e91996-12-10 23:23:01 +00002948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002949posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002950{
2951 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002952 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002953 return NULL;
2954 if (plock(op) == -1)
2955 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002956 Py_INCREF(Py_None);
2957 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002958}
2959#endif
2960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002962#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002964"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002966
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002967#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002968#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002969static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002970async_system(const char *command)
2971{
2972 char *p, errormsg[256], args[1024];
2973 RESULTCODES rcodes;
2974 APIRET rc;
2975 char *shell = getenv("COMSPEC");
2976 if (!shell)
2977 shell = "cmd";
2978
2979 strcpy(args, shell);
2980 p = &args[ strlen(args)+1 ];
2981 strcpy(p, "/c ");
2982 strcat(p, command);
2983 p += strlen(p) + 1;
2984 *p = '\0';
2985
2986 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002987 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002988 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002989 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002990 &rcodes, shell);
2991 return rc;
2992}
2993
Guido van Rossumd48f2521997-12-05 22:19:34 +00002994static FILE *
2995popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002996{
2997 HFILE rhan, whan;
2998 FILE *retfd = NULL;
2999 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3000
Guido van Rossumd48f2521997-12-05 22:19:34 +00003001 if (rc != NO_ERROR) {
3002 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003003 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003004 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003005
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003006 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3007 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003008
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003009 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3010 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003011
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003012 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3013 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003014
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003015 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003016 }
3017
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003018 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3019 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003020
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003021 if (rc == NO_ERROR)
3022 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3023
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003024 close(oldfd); /* And Close Saved STDOUT Handle */
3025 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003026
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003027 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3028 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003029
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003030 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3031 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003032
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003033 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3034 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003035
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003036 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003037 }
3038
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003039 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3040 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003041
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003042 if (rc == NO_ERROR)
3043 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003045 close(oldfd); /* And Close Saved STDIN Handle */
3046 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003047
Guido van Rossumd48f2521997-12-05 22:19:34 +00003048 } else {
3049 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003050 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003051 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003052}
3053
3054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003055posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003056{
3057 char *name;
3058 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003059 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003060 FILE *fp;
3061 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003062 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003063 return NULL;
3064 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003065 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003066 Py_END_ALLOW_THREADS
3067 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003068 return os2_error(err);
3069
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003070 f = PyFile_FromFile(fp, name, mode, fclose);
3071 if (f != NULL)
3072 PyFile_SetBufSize(f, bufsize);
3073 return f;
3074}
3075
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003076#elif defined(PYCC_GCC)
3077
3078/* standard posix version of popen() support */
3079static PyObject *
3080posix_popen(PyObject *self, PyObject *args)
3081{
3082 char *name;
3083 char *mode = "r";
3084 int bufsize = -1;
3085 FILE *fp;
3086 PyObject *f;
3087 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3088 return NULL;
3089 Py_BEGIN_ALLOW_THREADS
3090 fp = popen(name, mode);
3091 Py_END_ALLOW_THREADS
3092 if (fp == NULL)
3093 return posix_error();
3094 f = PyFile_FromFile(fp, name, mode, pclose);
3095 if (f != NULL)
3096 PyFile_SetBufSize(f, bufsize);
3097 return f;
3098}
3099
3100/* fork() under OS/2 has lots'o'warts
3101 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3102 * most of this code is a ripoff of the win32 code, but using the
3103 * capabilities of EMX's C library routines
3104 */
3105
3106/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3107#define POPEN_1 1
3108#define POPEN_2 2
3109#define POPEN_3 3
3110#define POPEN_4 4
3111
3112static PyObject *_PyPopen(char *, int, int, int);
3113static int _PyPclose(FILE *file);
3114
3115/*
3116 * Internal dictionary mapping popen* file pointers to process handles,
3117 * for use when retrieving the process exit code. See _PyPclose() below
3118 * for more information on this dictionary's use.
3119 */
3120static PyObject *_PyPopenProcs = NULL;
3121
3122/* os2emx version of popen2()
3123 *
3124 * The result of this function is a pipe (file) connected to the
3125 * process's stdin, and a pipe connected to the process's stdout.
3126 */
3127
3128static PyObject *
3129os2emx_popen2(PyObject *self, PyObject *args)
3130{
3131 PyObject *f;
3132 int tm=0;
3133
3134 char *cmdstring;
3135 char *mode = "t";
3136 int bufsize = -1;
3137 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3138 return NULL;
3139
3140 if (*mode == 't')
3141 tm = O_TEXT;
3142 else if (*mode != 'b') {
3143 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3144 return NULL;
3145 } else
3146 tm = O_BINARY;
3147
3148 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3149
3150 return f;
3151}
3152
3153/*
3154 * Variation on os2emx.popen2
3155 *
3156 * The result of this function is 3 pipes - the process's stdin,
3157 * stdout and stderr
3158 */
3159
3160static PyObject *
3161os2emx_popen3(PyObject *self, PyObject *args)
3162{
3163 PyObject *f;
3164 int tm = 0;
3165
3166 char *cmdstring;
3167 char *mode = "t";
3168 int bufsize = -1;
3169 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3170 return NULL;
3171
3172 if (*mode == 't')
3173 tm = O_TEXT;
3174 else if (*mode != 'b') {
3175 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3176 return NULL;
3177 } else
3178 tm = O_BINARY;
3179
3180 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3181
3182 return f;
3183}
3184
3185/*
3186 * Variation on os2emx.popen2
3187 *
3188 * The result of this function is 2 pipes - the processes stdin,
3189 * and stdout+stderr combined as a single pipe.
3190 */
3191
3192static PyObject *
3193os2emx_popen4(PyObject *self, PyObject *args)
3194{
3195 PyObject *f;
3196 int tm = 0;
3197
3198 char *cmdstring;
3199 char *mode = "t";
3200 int bufsize = -1;
3201 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3202 return NULL;
3203
3204 if (*mode == 't')
3205 tm = O_TEXT;
3206 else if (*mode != 'b') {
3207 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3208 return NULL;
3209 } else
3210 tm = O_BINARY;
3211
3212 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3213
3214 return f;
3215}
3216
3217/* a couple of structures for convenient handling of multiple
3218 * file handles and pipes
3219 */
3220struct file_ref
3221{
3222 int handle;
3223 int flags;
3224};
3225
3226struct pipe_ref
3227{
3228 int rd;
3229 int wr;
3230};
3231
3232/* The following code is derived from the win32 code */
3233
3234static PyObject *
3235_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3236{
3237 struct file_ref stdio[3];
3238 struct pipe_ref p_fd[3];
3239 FILE *p_s[3];
3240 int file_count, i, pipe_err, pipe_pid;
3241 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3242 PyObject *f, *p_f[3];
3243
3244 /* file modes for subsequent fdopen's on pipe handles */
3245 if (mode == O_TEXT)
3246 {
3247 rd_mode = "rt";
3248 wr_mode = "wt";
3249 }
3250 else
3251 {
3252 rd_mode = "rb";
3253 wr_mode = "wb";
3254 }
3255
3256 /* prepare shell references */
3257 if ((shell = getenv("EMXSHELL")) == NULL)
3258 if ((shell = getenv("COMSPEC")) == NULL)
3259 {
3260 errno = ENOENT;
3261 return posix_error();
3262 }
3263
3264 sh_name = _getname(shell);
3265 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3266 opt = "/c";
3267 else
3268 opt = "-c";
3269
3270 /* save current stdio fds + their flags, and set not inheritable */
3271 i = pipe_err = 0;
3272 while (pipe_err >= 0 && i < 3)
3273 {
3274 pipe_err = stdio[i].handle = dup(i);
3275 stdio[i].flags = fcntl(i, F_GETFD, 0);
3276 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3277 i++;
3278 }
3279 if (pipe_err < 0)
3280 {
3281 /* didn't get them all saved - clean up and bail out */
3282 int saved_err = errno;
3283 while (i-- > 0)
3284 {
3285 close(stdio[i].handle);
3286 }
3287 errno = saved_err;
3288 return posix_error();
3289 }
3290
3291 /* create pipe ends */
3292 file_count = 2;
3293 if (n == POPEN_3)
3294 file_count = 3;
3295 i = pipe_err = 0;
3296 while ((pipe_err == 0) && (i < file_count))
3297 pipe_err = pipe((int *)&p_fd[i++]);
3298 if (pipe_err < 0)
3299 {
3300 /* didn't get them all made - clean up and bail out */
3301 while (i-- > 0)
3302 {
3303 close(p_fd[i].wr);
3304 close(p_fd[i].rd);
3305 }
3306 errno = EPIPE;
3307 return posix_error();
3308 }
3309
3310 /* change the actual standard IO streams over temporarily,
3311 * making the retained pipe ends non-inheritable
3312 */
3313 pipe_err = 0;
3314
3315 /* - stdin */
3316 if (dup2(p_fd[0].rd, 0) == 0)
3317 {
3318 close(p_fd[0].rd);
3319 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3320 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3321 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3322 {
3323 close(p_fd[0].wr);
3324 pipe_err = -1;
3325 }
3326 }
3327 else
3328 {
3329 pipe_err = -1;
3330 }
3331
3332 /* - stdout */
3333 if (pipe_err == 0)
3334 {
3335 if (dup2(p_fd[1].wr, 1) == 1)
3336 {
3337 close(p_fd[1].wr);
3338 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3339 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3340 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3341 {
3342 close(p_fd[1].rd);
3343 pipe_err = -1;
3344 }
3345 }
3346 else
3347 {
3348 pipe_err = -1;
3349 }
3350 }
3351
3352 /* - stderr, as required */
3353 if (pipe_err == 0)
3354 switch (n)
3355 {
3356 case POPEN_3:
3357 {
3358 if (dup2(p_fd[2].wr, 2) == 2)
3359 {
3360 close(p_fd[2].wr);
3361 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3362 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3363 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3364 {
3365 close(p_fd[2].rd);
3366 pipe_err = -1;
3367 }
3368 }
3369 else
3370 {
3371 pipe_err = -1;
3372 }
3373 break;
3374 }
3375
3376 case POPEN_4:
3377 {
3378 if (dup2(1, 2) != 2)
3379 {
3380 pipe_err = -1;
3381 }
3382 break;
3383 }
3384 }
3385
3386 /* spawn the child process */
3387 if (pipe_err == 0)
3388 {
3389 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3390 if (pipe_pid == -1)
3391 {
3392 pipe_err = -1;
3393 }
3394 else
3395 {
3396 /* save the PID into the FILE structure
3397 * NOTE: this implementation doesn't actually
3398 * take advantage of this, but do it for
3399 * completeness - AIM Apr01
3400 */
3401 for (i = 0; i < file_count; i++)
3402 p_s[i]->_pid = pipe_pid;
3403 }
3404 }
3405
3406 /* reset standard IO to normal */
3407 for (i = 0; i < 3; i++)
3408 {
3409 dup2(stdio[i].handle, i);
3410 fcntl(i, F_SETFD, stdio[i].flags);
3411 close(stdio[i].handle);
3412 }
3413
3414 /* if any remnant problems, clean up and bail out */
3415 if (pipe_err < 0)
3416 {
3417 for (i = 0; i < 3; i++)
3418 {
3419 close(p_fd[i].rd);
3420 close(p_fd[i].wr);
3421 }
3422 errno = EPIPE;
3423 return posix_error_with_filename(cmdstring);
3424 }
3425
3426 /* build tuple of file objects to return */
3427 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3428 PyFile_SetBufSize(p_f[0], bufsize);
3429 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3430 PyFile_SetBufSize(p_f[1], bufsize);
3431 if (n == POPEN_3)
3432 {
3433 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3434 PyFile_SetBufSize(p_f[0], bufsize);
3435 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3436 }
3437 else
3438 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3439
3440 /*
3441 * Insert the files we've created into the process dictionary
3442 * all referencing the list with the process handle and the
3443 * initial number of files (see description below in _PyPclose).
3444 * Since if _PyPclose later tried to wait on a process when all
3445 * handles weren't closed, it could create a deadlock with the
3446 * child, we spend some energy here to try to ensure that we
3447 * either insert all file handles into the dictionary or none
3448 * at all. It's a little clumsy with the various popen modes
3449 * and variable number of files involved.
3450 */
3451 if (!_PyPopenProcs)
3452 {
3453 _PyPopenProcs = PyDict_New();
3454 }
3455
3456 if (_PyPopenProcs)
3457 {
3458 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3459 int ins_rc[3];
3460
3461 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3462 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3463
3464 procObj = PyList_New(2);
3465 pidObj = PyInt_FromLong((long) pipe_pid);
3466 intObj = PyInt_FromLong((long) file_count);
3467
3468 if (procObj && pidObj && intObj)
3469 {
3470 PyList_SetItem(procObj, 0, pidObj);
3471 PyList_SetItem(procObj, 1, intObj);
3472
3473 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3474 if (fileObj[0])
3475 {
3476 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3477 fileObj[0],
3478 procObj);
3479 }
3480 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3481 if (fileObj[1])
3482 {
3483 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3484 fileObj[1],
3485 procObj);
3486 }
3487 if (file_count >= 3)
3488 {
3489 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3490 if (fileObj[2])
3491 {
3492 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3493 fileObj[2],
3494 procObj);
3495 }
3496 }
3497
3498 if (ins_rc[0] < 0 || !fileObj[0] ||
3499 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3500 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3501 {
3502 /* Something failed - remove any dictionary
3503 * entries that did make it.
3504 */
3505 if (!ins_rc[0] && fileObj[0])
3506 {
3507 PyDict_DelItem(_PyPopenProcs,
3508 fileObj[0]);
3509 }
3510 if (!ins_rc[1] && fileObj[1])
3511 {
3512 PyDict_DelItem(_PyPopenProcs,
3513 fileObj[1]);
3514 }
3515 if (!ins_rc[2] && fileObj[2])
3516 {
3517 PyDict_DelItem(_PyPopenProcs,
3518 fileObj[2]);
3519 }
3520 }
3521 }
3522
3523 /*
3524 * Clean up our localized references for the dictionary keys
3525 * and value since PyDict_SetItem will Py_INCREF any copies
3526 * that got placed in the dictionary.
3527 */
3528 Py_XDECREF(procObj);
3529 Py_XDECREF(fileObj[0]);
3530 Py_XDECREF(fileObj[1]);
3531 Py_XDECREF(fileObj[2]);
3532 }
3533
3534 /* Child is launched. */
3535 return f;
3536}
3537
3538/*
3539 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3540 * exit code for the child process and return as a result of the close.
3541 *
3542 * This function uses the _PyPopenProcs dictionary in order to map the
3543 * input file pointer to information about the process that was
3544 * originally created by the popen* call that created the file pointer.
3545 * The dictionary uses the file pointer as a key (with one entry
3546 * inserted for each file returned by the original popen* call) and a
3547 * single list object as the value for all files from a single call.
3548 * The list object contains the Win32 process handle at [0], and a file
3549 * count at [1], which is initialized to the total number of file
3550 * handles using that list.
3551 *
3552 * This function closes whichever handle it is passed, and decrements
3553 * the file count in the dictionary for the process handle pointed to
3554 * by this file. On the last close (when the file count reaches zero),
3555 * this function will wait for the child process and then return its
3556 * exit code as the result of the close() operation. This permits the
3557 * files to be closed in any order - it is always the close() of the
3558 * final handle that will return the exit code.
3559 */
3560
3561 /* RED_FLAG 31-Aug-2000 Tim
3562 * This is always called (today!) between a pair of
3563 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3564 * macros. So the thread running this has no valid thread state, as
3565 * far as Python is concerned. However, this calls some Python API
3566 * functions that cannot be called safely without a valid thread
3567 * state, in particular PyDict_GetItem.
3568 * As a temporary hack (although it may last for years ...), we
3569 * *rely* on not having a valid thread state in this function, in
3570 * order to create our own "from scratch".
3571 * This will deadlock if _PyPclose is ever called by a thread
3572 * holding the global lock.
3573 * (The OS/2 EMX thread support appears to cover the case where the
3574 * lock is already held - AIM Apr01)
3575 */
3576
3577static int _PyPclose(FILE *file)
3578{
3579 int result;
3580 int exit_code;
3581 int pipe_pid;
3582 PyObject *procObj, *pidObj, *intObj, *fileObj;
3583 int file_count;
3584#ifdef WITH_THREAD
3585 PyInterpreterState* pInterpreterState;
3586 PyThreadState* pThreadState;
3587#endif
3588
3589 /* Close the file handle first, to ensure it can't block the
3590 * child from exiting if it's the last handle.
3591 */
3592 result = fclose(file);
3593
3594#ifdef WITH_THREAD
3595 /* Bootstrap a valid thread state into existence. */
3596 pInterpreterState = PyInterpreterState_New();
3597 if (!pInterpreterState) {
3598 /* Well, we're hosed now! We don't have a thread
3599 * state, so can't call a nice error routine, or raise
3600 * an exception. Just die.
3601 */
3602 Py_FatalError("unable to allocate interpreter state "
3603 "when closing popen object.");
3604 return -1; /* unreachable */
3605 }
3606 pThreadState = PyThreadState_New(pInterpreterState);
3607 if (!pThreadState) {
3608 Py_FatalError("unable to allocate thread state "
3609 "when closing popen object.");
3610 return -1; /* unreachable */
3611 }
3612 /* Grab the global lock. Note that this will deadlock if the
3613 * current thread already has the lock! (see RED_FLAG comments
3614 * before this function)
3615 */
3616 PyEval_RestoreThread(pThreadState);
3617#endif
3618
3619 if (_PyPopenProcs)
3620 {
3621 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3622 (procObj = PyDict_GetItem(_PyPopenProcs,
3623 fileObj)) != NULL &&
3624 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3625 (intObj = PyList_GetItem(procObj,1)) != NULL)
3626 {
3627 pipe_pid = (int) PyInt_AsLong(pidObj);
3628 file_count = (int) PyInt_AsLong(intObj);
3629
3630 if (file_count > 1)
3631 {
3632 /* Still other files referencing process */
3633 file_count--;
3634 PyList_SetItem(procObj,1,
3635 PyInt_FromLong((long) file_count));
3636 }
3637 else
3638 {
3639 /* Last file for this process */
3640 if (result != EOF &&
3641 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3642 {
3643 /* extract exit status */
3644 if (WIFEXITED(exit_code))
3645 {
3646 result = WEXITSTATUS(exit_code);
3647 }
3648 else
3649 {
3650 errno = EPIPE;
3651 result = -1;
3652 }
3653 }
3654 else
3655 {
3656 /* Indicate failure - this will cause the file object
3657 * to raise an I/O error and translate the last
3658 * error code from errno. We do have a problem with
3659 * last errors that overlap the normal errno table,
3660 * but that's a consistent problem with the file object.
3661 */
3662 result = -1;
3663 }
3664 }
3665
3666 /* Remove this file pointer from dictionary */
3667 PyDict_DelItem(_PyPopenProcs, fileObj);
3668
3669 if (PyDict_Size(_PyPopenProcs) == 0)
3670 {
3671 Py_DECREF(_PyPopenProcs);
3672 _PyPopenProcs = NULL;
3673 }
3674
3675 } /* if object retrieval ok */
3676
3677 Py_XDECREF(fileObj);
3678 } /* if _PyPopenProcs */
3679
3680#ifdef WITH_THREAD
3681 /* Tear down the thread & interpreter states.
3682 * Note that interpreter state clear & delete functions automatically
3683 * call the thread clear & delete functions, and indeed insist on
3684 * doing that themselves. The lock must be held during the clear, but
3685 * need not be held during the delete.
3686 */
3687 PyInterpreterState_Clear(pInterpreterState);
3688 PyEval_ReleaseThread(pThreadState);
3689 PyInterpreterState_Delete(pInterpreterState);
3690#endif
3691
3692 return result;
3693}
3694
3695#endif /* PYCC_??? */
3696
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003697#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003698
3699/*
3700 * Portable 'popen' replacement for Win32.
3701 *
3702 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3703 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003704 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 */
3706
3707#include <malloc.h>
3708#include <io.h>
3709#include <fcntl.h>
3710
3711/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3712#define POPEN_1 1
3713#define POPEN_2 2
3714#define POPEN_3 3
3715#define POPEN_4 4
3716
3717static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003718static int _PyPclose(FILE *file);
3719
3720/*
3721 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003722 * for use when retrieving the process exit code. See _PyPclose() below
3723 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003724 */
3725static PyObject *_PyPopenProcs = NULL;
3726
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003727
3728/* popen that works from a GUI.
3729 *
3730 * The result of this function is a pipe (file) connected to the
3731 * processes stdin or stdout, depending on the requested mode.
3732 */
3733
3734static PyObject *
3735posix_popen(PyObject *self, PyObject *args)
3736{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003737 PyObject *f, *s;
3738 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003739
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003740 char *cmdstring;
3741 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003742 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003743 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003744 return NULL;
3745
3746 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003747
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 if (*mode == 'r')
3749 tm = _O_RDONLY;
3750 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003751 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003752 return NULL;
3753 } else
3754 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003755
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003756 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003757 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003758 return NULL;
3759 }
3760
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003761 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003762 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003763 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003764 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003765 else
3766 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3767
3768 return f;
3769}
3770
3771/* Variation on win32pipe.popen
3772 *
3773 * The result of this function is a pipe (file) connected to the
3774 * process's stdin, and a pipe connected to the process's stdout.
3775 */
3776
3777static PyObject *
3778win32_popen2(PyObject *self, PyObject *args)
3779{
3780 PyObject *f;
3781 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003782
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003783 char *cmdstring;
3784 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003785 int bufsize = -1;
3786 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003787 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003788
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003789 if (*mode == 't')
3790 tm = _O_TEXT;
3791 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003792 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003793 return NULL;
3794 } else
3795 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003796
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003797 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003798 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003799 return NULL;
3800 }
3801
3802 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003803
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003804 return f;
3805}
3806
3807/*
3808 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003809 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003810 * The result of this function is 3 pipes - the process's stdin,
3811 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003812 */
3813
3814static PyObject *
3815win32_popen3(PyObject *self, PyObject *args)
3816{
3817 PyObject *f;
3818 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003819
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003820 char *cmdstring;
3821 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003822 int bufsize = -1;
3823 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003824 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003825
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003826 if (*mode == 't')
3827 tm = _O_TEXT;
3828 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003829 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003830 return NULL;
3831 } else
3832 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003833
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003834 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003835 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003836 return NULL;
3837 }
3838
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003839 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003840
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003841 return f;
3842}
3843
3844/*
3845 * Variation on win32pipe.popen
3846 *
Tim Peters5aa91602002-01-30 05:46:57 +00003847 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 * and stdout+stderr combined as a single pipe.
3849 */
3850
3851static PyObject *
3852win32_popen4(PyObject *self, PyObject *args)
3853{
3854 PyObject *f;
3855 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003856
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003857 char *cmdstring;
3858 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003859 int bufsize = -1;
3860 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003861 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003862
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003863 if (*mode == 't')
3864 tm = _O_TEXT;
3865 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003866 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003867 return NULL;
3868 } else
3869 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003870
3871 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003872 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003873 return NULL;
3874 }
3875
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003876 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003877
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003878 return f;
3879}
3880
Mark Hammond08501372001-01-31 07:30:29 +00003881static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003882_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003883 HANDLE hStdin,
3884 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003885 HANDLE hStderr,
3886 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003887{
3888 PROCESS_INFORMATION piProcInfo;
3889 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003890 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003891 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003892 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003893 int i;
3894 int x;
3895
3896 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003897 char *comshell;
3898
Tim Peters92e4dd82002-10-05 01:47:34 +00003899 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003900 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3901 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003902
3903 /* Explicitly check if we are using COMMAND.COM. If we are
3904 * then use the w9xpopen hack.
3905 */
3906 comshell = s1 + x;
3907 while (comshell >= s1 && *comshell != '\\')
3908 --comshell;
3909 ++comshell;
3910
3911 if (GetVersion() < 0x80000000 &&
3912 _stricmp(comshell, "command.com") != 0) {
3913 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003914 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003915 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003916 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003917 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003918 }
3919 else {
3920 /*
Tim Peters402d5982001-08-27 06:37:48 +00003921 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3922 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003923 */
Mark Hammond08501372001-01-31 07:30:29 +00003924 char modulepath[_MAX_PATH];
3925 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003926 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3927 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003928 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003929 x = i+1;
3930 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003931 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003932 strncat(modulepath,
3933 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003934 (sizeof(modulepath)/sizeof(modulepath[0]))
3935 -strlen(modulepath));
3936 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003937 /* Eeek - file-not-found - possibly an embedding
3938 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003939 */
Tim Peters5aa91602002-01-30 05:46:57 +00003940 strncpy(modulepath,
3941 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003942 sizeof(modulepath)/sizeof(modulepath[0]));
3943 if (modulepath[strlen(modulepath)-1] != '\\')
3944 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003945 strncat(modulepath,
3946 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003947 (sizeof(modulepath)/sizeof(modulepath[0]))
3948 -strlen(modulepath));
3949 /* No where else to look - raise an easily identifiable
3950 error, rather than leaving Windows to report
3951 "file not found" - as the user is probably blissfully
3952 unaware this shim EXE is used, and it will confuse them.
3953 (well, it confused me for a while ;-)
3954 */
3955 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003956 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003957 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003958 "for popen to work with your shell "
3959 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003960 szConsoleSpawn);
3961 return FALSE;
3962 }
3963 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003964 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003965 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003966 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003967
Tim Peters92e4dd82002-10-05 01:47:34 +00003968 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003969 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003970 /* To maintain correct argument passing semantics,
3971 we pass the command-line as it stands, and allow
3972 quoting to be applied. w9xpopen.exe will then
3973 use its argv vector, and re-quote the necessary
3974 args for the ultimate child process.
3975 */
Tim Peters75cdad52001-11-28 22:07:30 +00003976 PyOS_snprintf(
3977 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003978 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003979 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003980 s1,
3981 s3,
3982 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003983 /* Not passing CREATE_NEW_CONSOLE has been known to
3984 cause random failures on win9x. Specifically a
3985 dialog:
3986 "Your program accessed mem currently in use at xxx"
3987 and a hopeful warning about the stability of your
3988 system.
3989 Cost is Ctrl+C wont kill children, but anyone
3990 who cares can have a go!
3991 */
3992 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 }
3994 }
3995
3996 /* Could be an else here to try cmd.exe / command.com in the path
3997 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003998 else {
Tim Peters402d5982001-08-27 06:37:48 +00003999 PyErr_SetString(PyExc_RuntimeError,
4000 "Cannot locate a COMSPEC environment variable to "
4001 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004002 return FALSE;
4003 }
Tim Peters5aa91602002-01-30 05:46:57 +00004004
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004005 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4006 siStartInfo.cb = sizeof(STARTUPINFO);
4007 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4008 siStartInfo.hStdInput = hStdin;
4009 siStartInfo.hStdOutput = hStdout;
4010 siStartInfo.hStdError = hStderr;
4011 siStartInfo.wShowWindow = SW_HIDE;
4012
4013 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004014 s2,
4015 NULL,
4016 NULL,
4017 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004018 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004019 NULL,
4020 NULL,
4021 &siStartInfo,
4022 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004023 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004024 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004025
Mark Hammondb37a3732000-08-14 04:47:33 +00004026 /* Return process handle */
4027 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004028 return TRUE;
4029 }
Tim Peters402d5982001-08-27 06:37:48 +00004030 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004031 return FALSE;
4032}
4033
4034/* The following code is based off of KB: Q190351 */
4035
4036static PyObject *
4037_PyPopen(char *cmdstring, int mode, int n)
4038{
4039 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4040 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004041 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004042
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004043 SECURITY_ATTRIBUTES saAttr;
4044 BOOL fSuccess;
4045 int fd1, fd2, fd3;
4046 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004047 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004048 PyObject *f;
4049
4050 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4051 saAttr.bInheritHandle = TRUE;
4052 saAttr.lpSecurityDescriptor = NULL;
4053
4054 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4055 return win32_error("CreatePipe", NULL);
4056
4057 /* Create new output read handle and the input write handle. Set
4058 * the inheritance properties to FALSE. Otherwise, the child inherits
4059 * the these handles; resulting in non-closeable handles to the pipes
4060 * being created. */
4061 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004062 GetCurrentProcess(), &hChildStdinWrDup, 0,
4063 FALSE,
4064 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004065 if (!fSuccess)
4066 return win32_error("DuplicateHandle", NULL);
4067
4068 /* Close the inheritable version of ChildStdin
4069 that we're using. */
4070 CloseHandle(hChildStdinWr);
4071
4072 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4073 return win32_error("CreatePipe", NULL);
4074
4075 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004076 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4077 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004078 if (!fSuccess)
4079 return win32_error("DuplicateHandle", NULL);
4080
4081 /* Close the inheritable version of ChildStdout
4082 that we're using. */
4083 CloseHandle(hChildStdoutRd);
4084
4085 if (n != POPEN_4) {
4086 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4087 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004088 fSuccess = DuplicateHandle(GetCurrentProcess(),
4089 hChildStderrRd,
4090 GetCurrentProcess(),
4091 &hChildStderrRdDup, 0,
4092 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004093 if (!fSuccess)
4094 return win32_error("DuplicateHandle", NULL);
4095 /* Close the inheritable version of ChildStdErr that we're using. */
4096 CloseHandle(hChildStderrRd);
4097 }
Tim Peters5aa91602002-01-30 05:46:57 +00004098
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004099 switch (n) {
4100 case POPEN_1:
4101 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4102 case _O_WRONLY | _O_TEXT:
4103 /* Case for writing to child Stdin in text mode. */
4104 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4105 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004106 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004107 PyFile_SetBufSize(f, 0);
4108 /* We don't care about these pipes anymore, so close them. */
4109 CloseHandle(hChildStdoutRdDup);
4110 CloseHandle(hChildStderrRdDup);
4111 break;
4112
4113 case _O_RDONLY | _O_TEXT:
4114 /* Case for reading from child Stdout in text mode. */
4115 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4116 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004117 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004118 PyFile_SetBufSize(f, 0);
4119 /* We don't care about these pipes anymore, so close them. */
4120 CloseHandle(hChildStdinWrDup);
4121 CloseHandle(hChildStderrRdDup);
4122 break;
4123
4124 case _O_RDONLY | _O_BINARY:
4125 /* Case for readinig from child Stdout in binary mode. */
4126 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4127 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004128 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004129 PyFile_SetBufSize(f, 0);
4130 /* We don't care about these pipes anymore, so close them. */
4131 CloseHandle(hChildStdinWrDup);
4132 CloseHandle(hChildStderrRdDup);
4133 break;
4134
4135 case _O_WRONLY | _O_BINARY:
4136 /* Case for writing to child Stdin in binary mode. */
4137 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4138 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004139 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004140 PyFile_SetBufSize(f, 0);
4141 /* We don't care about these pipes anymore, so close them. */
4142 CloseHandle(hChildStdoutRdDup);
4143 CloseHandle(hChildStderrRdDup);
4144 break;
4145 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004146 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004147 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004148
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004149 case POPEN_2:
4150 case POPEN_4:
4151 {
4152 char *m1, *m2;
4153 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004154
Tim Peters7dca21e2002-08-19 00:42:29 +00004155 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004156 m1 = "r";
4157 m2 = "w";
4158 } else {
4159 m1 = "rb";
4160 m2 = "wb";
4161 }
4162
4163 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4164 f1 = _fdopen(fd1, m2);
4165 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4166 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004167 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004168 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004169 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004170 PyFile_SetBufSize(p2, 0);
4171
4172 if (n != 4)
4173 CloseHandle(hChildStderrRdDup);
4174
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004175 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004176 Py_XDECREF(p1);
4177 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004178 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004179 break;
4180 }
Tim Peters5aa91602002-01-30 05:46:57 +00004181
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004182 case POPEN_3:
4183 {
4184 char *m1, *m2;
4185 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004186
Tim Peters7dca21e2002-08-19 00:42:29 +00004187 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004188 m1 = "r";
4189 m2 = "w";
4190 } else {
4191 m1 = "rb";
4192 m2 = "wb";
4193 }
4194
4195 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4196 f1 = _fdopen(fd1, m2);
4197 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4198 f2 = _fdopen(fd2, m1);
4199 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4200 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004201 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004202 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4203 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004204 PyFile_SetBufSize(p1, 0);
4205 PyFile_SetBufSize(p2, 0);
4206 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004207 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004208 Py_XDECREF(p1);
4209 Py_XDECREF(p2);
4210 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004211 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004212 break;
4213 }
4214 }
4215
4216 if (n == POPEN_4) {
4217 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004218 hChildStdinRd,
4219 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004220 hChildStdoutWr,
4221 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004222 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004223 }
4224 else {
4225 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004226 hChildStdinRd,
4227 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004228 hChildStderrWr,
4229 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004230 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 }
4232
Mark Hammondb37a3732000-08-14 04:47:33 +00004233 /*
4234 * Insert the files we've created into the process dictionary
4235 * all referencing the list with the process handle and the
4236 * initial number of files (see description below in _PyPclose).
4237 * Since if _PyPclose later tried to wait on a process when all
4238 * handles weren't closed, it could create a deadlock with the
4239 * child, we spend some energy here to try to ensure that we
4240 * either insert all file handles into the dictionary or none
4241 * at all. It's a little clumsy with the various popen modes
4242 * and variable number of files involved.
4243 */
4244 if (!_PyPopenProcs) {
4245 _PyPopenProcs = PyDict_New();
4246 }
4247
4248 if (_PyPopenProcs) {
4249 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4250 int ins_rc[3];
4251
4252 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4253 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4254
4255 procObj = PyList_New(2);
4256 hProcessObj = PyLong_FromVoidPtr(hProcess);
4257 intObj = PyInt_FromLong(file_count);
4258
4259 if (procObj && hProcessObj && intObj) {
4260 PyList_SetItem(procObj,0,hProcessObj);
4261 PyList_SetItem(procObj,1,intObj);
4262
4263 fileObj[0] = PyLong_FromVoidPtr(f1);
4264 if (fileObj[0]) {
4265 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4266 fileObj[0],
4267 procObj);
4268 }
4269 if (file_count >= 2) {
4270 fileObj[1] = PyLong_FromVoidPtr(f2);
4271 if (fileObj[1]) {
4272 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4273 fileObj[1],
4274 procObj);
4275 }
4276 }
4277 if (file_count >= 3) {
4278 fileObj[2] = PyLong_FromVoidPtr(f3);
4279 if (fileObj[2]) {
4280 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4281 fileObj[2],
4282 procObj);
4283 }
4284 }
4285
4286 if (ins_rc[0] < 0 || !fileObj[0] ||
4287 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4288 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4289 /* Something failed - remove any dictionary
4290 * entries that did make it.
4291 */
4292 if (!ins_rc[0] && fileObj[0]) {
4293 PyDict_DelItem(_PyPopenProcs,
4294 fileObj[0]);
4295 }
4296 if (!ins_rc[1] && fileObj[1]) {
4297 PyDict_DelItem(_PyPopenProcs,
4298 fileObj[1]);
4299 }
4300 if (!ins_rc[2] && fileObj[2]) {
4301 PyDict_DelItem(_PyPopenProcs,
4302 fileObj[2]);
4303 }
4304 }
4305 }
Tim Peters5aa91602002-01-30 05:46:57 +00004306
Mark Hammondb37a3732000-08-14 04:47:33 +00004307 /*
4308 * Clean up our localized references for the dictionary keys
4309 * and value since PyDict_SetItem will Py_INCREF any copies
4310 * that got placed in the dictionary.
4311 */
4312 Py_XDECREF(procObj);
4313 Py_XDECREF(fileObj[0]);
4314 Py_XDECREF(fileObj[1]);
4315 Py_XDECREF(fileObj[2]);
4316 }
4317
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318 /* Child is launched. Close the parents copy of those pipe
4319 * handles that only the child should have open. You need to
4320 * make sure that no handles to the write end of the output pipe
4321 * are maintained in this process or else the pipe will not close
4322 * when the child process exits and the ReadFile will hang. */
4323
4324 if (!CloseHandle(hChildStdinRd))
4325 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004326
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004327 if (!CloseHandle(hChildStdoutWr))
4328 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004329
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004330 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4331 return win32_error("CloseHandle", NULL);
4332
4333 return f;
4334}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004335
4336/*
4337 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4338 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004339 *
4340 * This function uses the _PyPopenProcs dictionary in order to map the
4341 * input file pointer to information about the process that was
4342 * originally created by the popen* call that created the file pointer.
4343 * The dictionary uses the file pointer as a key (with one entry
4344 * inserted for each file returned by the original popen* call) and a
4345 * single list object as the value for all files from a single call.
4346 * The list object contains the Win32 process handle at [0], and a file
4347 * count at [1], which is initialized to the total number of file
4348 * handles using that list.
4349 *
4350 * This function closes whichever handle it is passed, and decrements
4351 * the file count in the dictionary for the process handle pointed to
4352 * by this file. On the last close (when the file count reaches zero),
4353 * this function will wait for the child process and then return its
4354 * exit code as the result of the close() operation. This permits the
4355 * files to be closed in any order - it is always the close() of the
4356 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004357 *
4358 * NOTE: This function is currently called with the GIL released.
4359 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004360 */
Tim Peters736aa322000-09-01 06:51:24 +00004361
Fredrik Lundh56055a42000-07-23 19:47:12 +00004362static int _PyPclose(FILE *file)
4363{
Fredrik Lundh20318932000-07-26 17:29:12 +00004364 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004365 DWORD exit_code;
4366 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004367 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4368 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004369#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004370 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004371#endif
4372
Fredrik Lundh20318932000-07-26 17:29:12 +00004373 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004374 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004375 */
4376 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004377#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004378 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004379#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004380 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004381 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4382 (procObj = PyDict_GetItem(_PyPopenProcs,
4383 fileObj)) != NULL &&
4384 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4385 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4386
4387 hProcess = PyLong_AsVoidPtr(hProcessObj);
4388 file_count = PyInt_AsLong(intObj);
4389
4390 if (file_count > 1) {
4391 /* Still other files referencing process */
4392 file_count--;
4393 PyList_SetItem(procObj,1,
4394 PyInt_FromLong(file_count));
4395 } else {
4396 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004397 if (result != EOF &&
4398 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4399 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004400 /* Possible truncation here in 16-bit environments, but
4401 * real exit codes are just the lower byte in any event.
4402 */
4403 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004404 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004405 /* Indicate failure - this will cause the file object
4406 * to raise an I/O error and translate the last Win32
4407 * error code from errno. We do have a problem with
4408 * last errors that overlap the normal errno table,
4409 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004410 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004411 if (result != EOF) {
4412 /* If the error wasn't from the fclose(), then
4413 * set errno for the file object error handling.
4414 */
4415 errno = GetLastError();
4416 }
4417 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004418 }
4419
4420 /* Free up the native handle at this point */
4421 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004422 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004423
Mark Hammondb37a3732000-08-14 04:47:33 +00004424 /* Remove this file pointer from dictionary */
4425 PyDict_DelItem(_PyPopenProcs, fileObj);
4426
4427 if (PyDict_Size(_PyPopenProcs) == 0) {
4428 Py_DECREF(_PyPopenProcs);
4429 _PyPopenProcs = NULL;
4430 }
4431
4432 } /* if object retrieval ok */
4433
4434 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004435 } /* if _PyPopenProcs */
4436
Tim Peters736aa322000-09-01 06:51:24 +00004437#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004438 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004439#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004440 return result;
4441}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004442
4443#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004446{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004447 char *name;
4448 char *mode = "r";
4449 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004450 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004451 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004452 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004453 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004455 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004456 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004457 if (fp == NULL)
4458 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004459 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004460 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004461 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004462 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004463}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004464
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004465#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004466#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004468
Guido van Rossumb6775db1994-08-01 11:34:53 +00004469#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004470PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004471"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004472Set the current process's user id.");
4473
Barry Warsaw53699e91996-12-10 23:23:01 +00004474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004475posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004476{
4477 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004478 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004479 return NULL;
4480 if (setuid(uid) < 0)
4481 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004482 Py_INCREF(Py_None);
4483 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004484}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004485#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004487
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004488#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004490"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491Set the current process's effective user id.");
4492
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004493static PyObject *
4494posix_seteuid (PyObject *self, PyObject *args)
4495{
4496 int euid;
4497 if (!PyArg_ParseTuple(args, "i", &euid)) {
4498 return NULL;
4499 } else if (seteuid(euid) < 0) {
4500 return posix_error();
4501 } else {
4502 Py_INCREF(Py_None);
4503 return Py_None;
4504 }
4505}
4506#endif /* HAVE_SETEUID */
4507
4508#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004509PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004510"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511Set the current process's effective group id.");
4512
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004513static PyObject *
4514posix_setegid (PyObject *self, PyObject *args)
4515{
4516 int egid;
4517 if (!PyArg_ParseTuple(args, "i", &egid)) {
4518 return NULL;
4519 } else if (setegid(egid) < 0) {
4520 return posix_error();
4521 } else {
4522 Py_INCREF(Py_None);
4523 return Py_None;
4524 }
4525}
4526#endif /* HAVE_SETEGID */
4527
4528#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004529PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004530"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004531Set the current process's real and effective user ids.");
4532
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004533static PyObject *
4534posix_setreuid (PyObject *self, PyObject *args)
4535{
4536 int ruid, euid;
4537 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4538 return NULL;
4539 } else if (setreuid(ruid, euid) < 0) {
4540 return posix_error();
4541 } else {
4542 Py_INCREF(Py_None);
4543 return Py_None;
4544 }
4545}
4546#endif /* HAVE_SETREUID */
4547
4548#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004549PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004550"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004551Set the current process's real and effective group ids.");
4552
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004553static PyObject *
4554posix_setregid (PyObject *self, PyObject *args)
4555{
4556 int rgid, egid;
4557 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4558 return NULL;
4559 } else if (setregid(rgid, egid) < 0) {
4560 return posix_error();
4561 } else {
4562 Py_INCREF(Py_None);
4563 return Py_None;
4564 }
4565}
4566#endif /* HAVE_SETREGID */
4567
Guido van Rossumb6775db1994-08-01 11:34:53 +00004568#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004569PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004570"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004571Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004572
Barry Warsaw53699e91996-12-10 23:23:01 +00004573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004574posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004575{
4576 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004577 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004578 return NULL;
4579 if (setgid(gid) < 0)
4580 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004581 Py_INCREF(Py_None);
4582 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004583}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004584#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004585
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004586#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004588"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004589Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004590
4591static PyObject *
4592posix_setgroups(PyObject *self, PyObject *args)
4593{
4594 PyObject *groups;
4595 int i, len;
4596 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004597
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004598 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4599 return NULL;
4600 if (!PySequence_Check(groups)) {
4601 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4602 return NULL;
4603 }
4604 len = PySequence_Size(groups);
4605 if (len > MAX_GROUPS) {
4606 PyErr_SetString(PyExc_ValueError, "too many groups");
4607 return NULL;
4608 }
4609 for(i = 0; i < len; i++) {
4610 PyObject *elem;
4611 elem = PySequence_GetItem(groups, i);
4612 if (!elem)
4613 return NULL;
4614 if (!PyInt_Check(elem)) {
4615 PyErr_SetString(PyExc_TypeError,
4616 "groups must be integers");
4617 Py_DECREF(elem);
4618 return NULL;
4619 }
4620 /* XXX: check that value fits into gid_t. */
4621 grouplist[i] = PyInt_AsLong(elem);
4622 Py_DECREF(elem);
4623 }
4624
4625 if (setgroups(len, grouplist) < 0)
4626 return posix_error();
4627 Py_INCREF(Py_None);
4628 return Py_None;
4629}
4630#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004631
Guido van Rossumb6775db1994-08-01 11:34:53 +00004632#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004634"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004636
Barry Warsaw53699e91996-12-10 23:23:01 +00004637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004638posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004639{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004640 int pid, options;
4641#ifdef UNION_WAIT
4642 union wait status;
4643#define status_i (status.w_status)
4644#else
4645 int status;
4646#define status_i status
4647#endif
4648 status_i = 0;
4649
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004650 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004651 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004652 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004653 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004654 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004655 if (pid == -1)
4656 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004657 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004658 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004659}
4660
Tim Petersab034fa2002-02-01 11:27:43 +00004661#elif defined(HAVE_CWAIT)
4662
4663/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004665"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004666"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004667
4668static PyObject *
4669posix_waitpid(PyObject *self, PyObject *args)
4670{
4671 int pid, options;
4672 int status;
4673
4674 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4675 return NULL;
4676 Py_BEGIN_ALLOW_THREADS
4677 pid = _cwait(&status, pid, options);
4678 Py_END_ALLOW_THREADS
4679 if (pid == -1)
4680 return posix_error();
4681 else
4682 /* shift the status left a byte so this is more like the
4683 POSIX waitpid */
4684 return Py_BuildValue("ii", pid, status << 8);
4685}
4686#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004687
Guido van Rossumad0ee831995-03-01 10:34:45 +00004688#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004689PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004690"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004691Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004692
Barry Warsaw53699e91996-12-10 23:23:01 +00004693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004694posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004695{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004696 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004697#ifdef UNION_WAIT
4698 union wait status;
4699#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004700#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004701 int status;
4702#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004703#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004704
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004705 status_i = 0;
4706 Py_BEGIN_ALLOW_THREADS
4707 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004708 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004709 if (pid == -1)
4710 return posix_error();
4711 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004712 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004713#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004714}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004715#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004719"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004720Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004721
Barry Warsaw53699e91996-12-10 23:23:01 +00004722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004723posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004724{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004725#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004726 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004727#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004728#ifdef MS_WINDOWS
4729 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4730#else
4731 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4732#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004733#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004734}
4735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004736
Guido van Rossumb6775db1994-08-01 11:34:53 +00004737#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004739"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004740Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004741
Barry Warsaw53699e91996-12-10 23:23:01 +00004742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004743posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004744{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004745 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004746 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004747 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004748 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004749 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004750 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004751 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004752 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004753 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004754 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004755 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004756}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004757#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004759
Guido van Rossumb6775db1994-08-01 11:34:53 +00004760#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004762"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004763Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004764
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004766posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004767{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004768 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004769}
4770#endif /* HAVE_SYMLINK */
4771
4772
4773#ifdef HAVE_TIMES
4774#ifndef HZ
4775#define HZ 60 /* Universal constant :-) */
4776#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004777
Guido van Rossumd48f2521997-12-05 22:19:34 +00004778#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4779static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004780system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004781{
4782 ULONG value = 0;
4783
4784 Py_BEGIN_ALLOW_THREADS
4785 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4786 Py_END_ALLOW_THREADS
4787
4788 return value;
4789}
4790
4791static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004792posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004793{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004794 /* Currently Only Uptime is Provided -- Others Later */
4795 return Py_BuildValue("ddddd",
4796 (double)0 /* t.tms_utime / HZ */,
4797 (double)0 /* t.tms_stime / HZ */,
4798 (double)0 /* t.tms_cutime / HZ */,
4799 (double)0 /* t.tms_cstime / HZ */,
4800 (double)system_uptime() / 1000);
4801}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004802#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004803static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004804posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004805{
4806 struct tms t;
4807 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004808 errno = 0;
4809 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004810 if (c == (clock_t) -1)
4811 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004812 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004813 (double)t.tms_utime / HZ,
4814 (double)t.tms_stime / HZ,
4815 (double)t.tms_cutime / HZ,
4816 (double)t.tms_cstime / HZ,
4817 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004818}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004819#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004820#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004821
4822
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004823#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004824#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004825static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004826posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004827{
4828 FILETIME create, exit, kernel, user;
4829 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004830 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004831 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4832 /* The fields of a FILETIME structure are the hi and lo part
4833 of a 64-bit value expressed in 100 nanosecond units.
4834 1e7 is one second in such units; 1e-7 the inverse.
4835 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4836 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004837 return Py_BuildValue(
4838 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004839 (double)(kernel.dwHighDateTime*429.4967296 +
4840 kernel.dwLowDateTime*1e-7),
4841 (double)(user.dwHighDateTime*429.4967296 +
4842 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004843 (double)0,
4844 (double)0,
4845 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004846}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004847#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004848
4849#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004851"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004852Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004853#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004855
Guido van Rossumb6775db1994-08-01 11:34:53 +00004856#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004857PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004858"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004859Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004860
Barry Warsaw53699e91996-12-10 23:23:01 +00004861static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004862posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004863{
Guido van Rossum687dd131993-05-17 08:34:16 +00004864 if (setsid() < 0)
4865 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_INCREF(Py_None);
4867 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004868}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004869#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004870
Guido van Rossumb6775db1994-08-01 11:34:53 +00004871#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004872PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004873"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004874Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004875
Barry Warsaw53699e91996-12-10 23:23:01 +00004876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004877posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004878{
4879 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004880 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004881 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004882 if (setpgid(pid, pgrp) < 0)
4883 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_INCREF(Py_None);
4885 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004886}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004887#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004888
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004889
Guido van Rossumb6775db1994-08-01 11:34:53 +00004890#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004892"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004894
Barry Warsaw53699e91996-12-10 23:23:01 +00004895static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004896posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004897{
4898 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004899 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004900 return NULL;
4901 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004902 if (pgid < 0)
4903 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004905}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004906#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004907
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004908
Guido van Rossumb6775db1994-08-01 11:34:53 +00004909#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004910PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004911"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004912Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004913
Barry Warsaw53699e91996-12-10 23:23:01 +00004914static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004915posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004916{
4917 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004918 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004919 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004920 if (tcsetpgrp(fd, pgid) < 0)
4921 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004922 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004923 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004924}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004925#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004926
Guido van Rossum687dd131993-05-17 08:34:16 +00004927/* Functions acting on file descriptors */
4928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004929PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004930"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004931Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004932
Barry Warsaw53699e91996-12-10 23:23:01 +00004933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004934posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004935{
Mark Hammondef8b6542001-05-13 08:04:26 +00004936 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004937 int flag;
4938 int mode = 0777;
4939 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004940
4941#ifdef MS_WINDOWS
4942 if (unicode_file_names()) {
4943 PyUnicodeObject *po;
4944 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4945 Py_BEGIN_ALLOW_THREADS
4946 /* PyUnicode_AS_UNICODE OK without thread
4947 lock as it is a simple dereference. */
4948 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4949 Py_END_ALLOW_THREADS
4950 if (fd < 0)
4951 return posix_error();
4952 return PyInt_FromLong((long)fd);
4953 }
4954 /* Drop the argument parsing error as narrow strings
4955 are also valid. */
4956 PyErr_Clear();
4957 }
4958#endif
4959
Tim Peters5aa91602002-01-30 05:46:57 +00004960 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004961 Py_FileSystemDefaultEncoding, &file,
4962 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004963 return NULL;
4964
Barry Warsaw53699e91996-12-10 23:23:01 +00004965 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004966 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004967 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004968 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004969 return posix_error_with_allocated_filename(file);
4970 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004971 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004972}
4973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004974
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004977Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004978
Barry Warsaw53699e91996-12-10 23:23:01 +00004979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004980posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004981{
4982 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004985 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004986 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004987 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004988 if (res < 0)
4989 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004990 Py_INCREF(Py_None);
4991 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004992}
4993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004996"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004997Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004998
Barry Warsaw53699e91996-12-10 23:23:01 +00004999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005000posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005001{
5002 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005003 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005007 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005008 if (fd < 0)
5009 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005010 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005011}
5012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005019posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005020{
5021 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005022 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005025 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005026 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005027 if (res < 0)
5028 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005029 Py_INCREF(Py_None);
5030 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005031}
5032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005034PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005035"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005036Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005037
Barry Warsaw53699e91996-12-10 23:23:01 +00005038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005039posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005040{
5041 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005042#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005043 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005044#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005045 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005046#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005047 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005048 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005049 return NULL;
5050#ifdef SEEK_SET
5051 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5052 switch (how) {
5053 case 0: how = SEEK_SET; break;
5054 case 1: how = SEEK_CUR; break;
5055 case 2: how = SEEK_END; break;
5056 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005057#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005058
5059#if !defined(HAVE_LARGEFILE_SUPPORT)
5060 pos = PyInt_AsLong(posobj);
5061#else
5062 pos = PyLong_Check(posobj) ?
5063 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5064#endif
5065 if (PyErr_Occurred())
5066 return NULL;
5067
Barry Warsaw53699e91996-12-10 23:23:01 +00005068 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005069#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005070 res = _lseeki64(fd, pos, how);
5071#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005072 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005073#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005074 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005075 if (res < 0)
5076 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005077
5078#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005079 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005080#else
5081 return PyLong_FromLongLong(res);
5082#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005083}
5084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Barry Warsaw53699e91996-12-10 23:23:01 +00005090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005091posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005092{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005093 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005094 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005095 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005096 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005097 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005098 if (buffer == NULL)
5099 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005100 Py_BEGIN_ALLOW_THREADS
5101 n = read(fd, PyString_AsString(buffer), size);
5102 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005103 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005104 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005105 return posix_error();
5106 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005107 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005108 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005109 return buffer;
5110}
5111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005113PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005114"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005115Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005116
Barry Warsaw53699e91996-12-10 23:23:01 +00005117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005118posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005119{
5120 int fd, size;
5121 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005122 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005123 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005124 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005125 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005126 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005127 if (size < 0)
5128 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005129 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005130}
5131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005133PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005134"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005135Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005136
Barry Warsaw53699e91996-12-10 23:23:01 +00005137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005138posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005139{
5140 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005141 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005142 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005143 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005144 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005145#ifdef __VMS
5146 /* on OpenVMS we must ensure that all bytes are written to the file */
5147 fsync(fd);
5148#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005149 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005150 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005151 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005152 if (res != 0)
5153 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005154
Fred Drake699f3522000-06-29 21:12:41 +00005155 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005156}
5157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005158
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005159PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005160"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005161Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005162
Barry Warsaw53699e91996-12-10 23:23:01 +00005163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005164posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005165{
Guido van Rossum687dd131993-05-17 08:34:16 +00005166 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005167 char *mode = "r";
5168 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005169 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005170 PyObject *f;
5171 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005172 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005173
Thomas Heller1f043e22002-11-07 16:00:59 +00005174 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5175 PyErr_Format(PyExc_ValueError,
5176 "invalid file mode '%s'", mode);
5177 return NULL;
5178 }
5179
Barry Warsaw53699e91996-12-10 23:23:01 +00005180 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005181 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005182 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005183 if (fp == NULL)
5184 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005185 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005186 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005187 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005188 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005189}
5190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005193Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005194connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005195
5196static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005197posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005198{
5199 int fd;
5200 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5201 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005202 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005203}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005204
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005205#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005207"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005209
Barry Warsaw53699e91996-12-10 23:23:01 +00005210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005211posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005212{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005213#if defined(PYOS_OS2)
5214 HFILE read, write;
5215 APIRET rc;
5216
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005217 Py_BEGIN_ALLOW_THREADS
5218 rc = DosCreatePipe( &read, &write, 4096);
5219 Py_END_ALLOW_THREADS
5220 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005221 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005222
5223 return Py_BuildValue("(ii)", read, write);
5224#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005225#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005226 int fds[2];
5227 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005228 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005229#if defined(__VMS)
5230 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5231#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005232 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005233#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005234 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005235 if (res != 0)
5236 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005237 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005238#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005239 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005240 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005241 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005242 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005243 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005244 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005245 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005246 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005247 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5248 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005249 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005250#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005251#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005252}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005253#endif /* HAVE_PIPE */
5254
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005255
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005256#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005258"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005260
Barry Warsaw53699e91996-12-10 23:23:01 +00005261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005262posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005263{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005264 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005265 int mode = 0666;
5266 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005267 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005268 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005269 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005270 res = mkfifo(filename, mode);
5271 Py_END_ALLOW_THREADS
5272 if (res < 0)
5273 return posix_error();
5274 Py_INCREF(Py_None);
5275 return Py_None;
5276}
5277#endif
5278
5279
Neal Norwitz11690112002-07-30 01:08:28 +00005280#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005281PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005282"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005283Create a filesystem node (file, device special file or named pipe)\n\
5284named filename. mode specifies both the permissions to use and the\n\
5285type of node to be created, being combined (bitwise OR) with one of\n\
5286S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005287device defines the newly created device special file (probably using\n\
5288os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005289
5290
5291static PyObject *
5292posix_mknod(PyObject *self, PyObject *args)
5293{
5294 char *filename;
5295 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005296 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005297 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005298 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005299 return NULL;
5300 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005301 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005302 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005303 if (res < 0)
5304 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005305 Py_INCREF(Py_None);
5306 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005307}
5308#endif
5309
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005310#ifdef HAVE_DEVICE_MACROS
5311PyDoc_STRVAR(posix_major__doc__,
5312"major(device) -> major number\n\
5313Extracts a device major number from a raw device number.");
5314
5315static PyObject *
5316posix_major(PyObject *self, PyObject *args)
5317{
5318 int device;
5319 if (!PyArg_ParseTuple(args, "i:major", &device))
5320 return NULL;
5321 return PyInt_FromLong((long)major(device));
5322}
5323
5324PyDoc_STRVAR(posix_minor__doc__,
5325"minor(device) -> minor number\n\
5326Extracts a device minor number from a raw device number.");
5327
5328static PyObject *
5329posix_minor(PyObject *self, PyObject *args)
5330{
5331 int device;
5332 if (!PyArg_ParseTuple(args, "i:minor", &device))
5333 return NULL;
5334 return PyInt_FromLong((long)minor(device));
5335}
5336
5337PyDoc_STRVAR(posix_makedev__doc__,
5338"makedev(major, minor) -> device number\n\
5339Composes a raw device number from the major and minor device numbers.");
5340
5341static PyObject *
5342posix_makedev(PyObject *self, PyObject *args)
5343{
5344 int major, minor;
5345 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5346 return NULL;
5347 return PyInt_FromLong((long)makedev(major, minor));
5348}
5349#endif /* device macros */
5350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005351
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005352#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Barry Warsaw53699e91996-12-10 23:23:01 +00005357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005358posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005359{
5360 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005361 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005362 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005363 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005364
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005365 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005366 return NULL;
5367
5368#if !defined(HAVE_LARGEFILE_SUPPORT)
5369 length = PyInt_AsLong(lenobj);
5370#else
5371 length = PyLong_Check(lenobj) ?
5372 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5373#endif
5374 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005375 return NULL;
5376
Barry Warsaw53699e91996-12-10 23:23:01 +00005377 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005378 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005379 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005380 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005381 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005382 return NULL;
5383 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005384 Py_INCREF(Py_None);
5385 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005386}
5387#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005388
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005389#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005391"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005392Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005393
Fred Drake762e2061999-08-26 17:23:54 +00005394/* Save putenv() parameters as values here, so we can collect them when they
5395 * get re-set with another call for the same key. */
5396static PyObject *posix_putenv_garbage;
5397
Tim Peters5aa91602002-01-30 05:46:57 +00005398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005399posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005400{
5401 char *s1, *s2;
5402 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005403 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005404 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005405
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005406 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005407 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005408
5409#if defined(PYOS_OS2)
5410 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5411 APIRET rc;
5412
5413 if (strlen(s2) == 0) /* If New Value is an Empty String */
5414 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5415
5416 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5417 if (rc != NO_ERROR)
5418 return os2_error(rc);
5419
5420 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5421 APIRET rc;
5422
5423 if (strlen(s2) == 0) /* If New Value is an Empty String */
5424 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5425
5426 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5427 if (rc != NO_ERROR)
5428 return os2_error(rc);
5429 } else {
5430#endif
5431
Fred Drake762e2061999-08-26 17:23:54 +00005432 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005433 len = strlen(s1) + strlen(s2) + 2;
5434 /* len includes space for a trailing \0; the size arg to
5435 PyString_FromStringAndSize does not count that */
5436 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005437 if (newstr == NULL)
5438 return PyErr_NoMemory();
5439 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005440 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005441 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005442 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005443 posix_error();
5444 return NULL;
5445 }
Fred Drake762e2061999-08-26 17:23:54 +00005446 /* Install the first arg and newstr in posix_putenv_garbage;
5447 * this will cause previous value to be collected. This has to
5448 * happen after the real putenv() call because the old value
5449 * was still accessible until then. */
5450 if (PyDict_SetItem(posix_putenv_garbage,
5451 PyTuple_GET_ITEM(args, 0), newstr)) {
5452 /* really not much we can do; just leak */
5453 PyErr_Clear();
5454 }
5455 else {
5456 Py_DECREF(newstr);
5457 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005458
5459#if defined(PYOS_OS2)
5460 }
5461#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005462 Py_INCREF(Py_None);
5463 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005464}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005465#endif /* putenv */
5466
Guido van Rossumc524d952001-10-19 01:31:59 +00005467#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005469"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005471
5472static PyObject *
5473posix_unsetenv(PyObject *self, PyObject *args)
5474{
5475 char *s1;
5476
5477 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5478 return NULL;
5479
5480 unsetenv(s1);
5481
5482 /* Remove the key from posix_putenv_garbage;
5483 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005484 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005485 * old value was still accessible until then.
5486 */
5487 if (PyDict_DelItem(posix_putenv_garbage,
5488 PyTuple_GET_ITEM(args, 0))) {
5489 /* really not much we can do; just leak */
5490 PyErr_Clear();
5491 }
5492
5493 Py_INCREF(Py_None);
5494 return Py_None;
5495}
5496#endif /* unsetenv */
5497
Guido van Rossumb6a47161997-09-15 22:54:34 +00005498#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005500"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005501Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005502
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005504posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005505{
5506 int code;
5507 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005508 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005509 return NULL;
5510 message = strerror(code);
5511 if (message == NULL) {
5512 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005513 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005514 return NULL;
5515 }
5516 return PyString_FromString(message);
5517}
5518#endif /* strerror */
5519
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005520
Guido van Rossumc9641791998-08-04 15:26:23 +00005521#ifdef HAVE_SYS_WAIT_H
5522
Fred Drake106c1a02002-04-23 15:58:02 +00005523#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005524PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005525"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005526Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005527
5528static PyObject *
5529posix_WCOREDUMP(PyObject *self, PyObject *args)
5530{
5531#ifdef UNION_WAIT
5532 union wait status;
5533#define status_i (status.w_status)
5534#else
5535 int status;
5536#define status_i status
5537#endif
5538 status_i = 0;
5539
5540 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5541 {
5542 return NULL;
5543 }
5544
5545 return PyBool_FromLong(WCOREDUMP(status));
5546#undef status_i
5547}
5548#endif /* WCOREDUMP */
5549
5550#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005551PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005552"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005553Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005554job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005555
5556static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005557posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005558{
5559#ifdef UNION_WAIT
5560 union wait status;
5561#define status_i (status.w_status)
5562#else
5563 int status;
5564#define status_i status
5565#endif
5566 status_i = 0;
5567
5568 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5569 {
5570 return NULL;
5571 }
5572
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005573 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005574#undef status_i
5575}
5576#endif /* WIFCONTINUED */
5577
Guido van Rossumc9641791998-08-04 15:26:23 +00005578#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005579PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005580"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005581Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005582
5583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005584posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005585{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005586#ifdef UNION_WAIT
5587 union wait status;
5588#define status_i (status.w_status)
5589#else
5590 int status;
5591#define status_i status
5592#endif
5593 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005594
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005595 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005596 {
5597 return NULL;
5598 }
Tim Peters5aa91602002-01-30 05:46:57 +00005599
Fred Drake106c1a02002-04-23 15:58:02 +00005600 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005601#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005602}
5603#endif /* WIFSTOPPED */
5604
5605#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005609
5610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005612{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005613#ifdef UNION_WAIT
5614 union wait status;
5615#define status_i (status.w_status)
5616#else
5617 int status;
5618#define status_i status
5619#endif
5620 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005621
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005623 {
5624 return NULL;
5625 }
Tim Peters5aa91602002-01-30 05:46:57 +00005626
Fred Drake106c1a02002-04-23 15:58:02 +00005627 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005629}
5630#endif /* WIFSIGNALED */
5631
5632#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005633PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005634"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005635Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005636system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005637
5638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005639posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005640{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005641#ifdef UNION_WAIT
5642 union wait status;
5643#define status_i (status.w_status)
5644#else
5645 int status;
5646#define status_i status
5647#endif
5648 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005649
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005650 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005651 {
5652 return NULL;
5653 }
Tim Peters5aa91602002-01-30 05:46:57 +00005654
Fred Drake106c1a02002-04-23 15:58:02 +00005655 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005657}
5658#endif /* WIFEXITED */
5659
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005660#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005662"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005663Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005664
5665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005666posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005667{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005668#ifdef UNION_WAIT
5669 union wait status;
5670#define status_i (status.w_status)
5671#else
5672 int status;
5673#define status_i status
5674#endif
5675 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005676
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005678 {
5679 return NULL;
5680 }
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Guido van Rossumc9641791998-08-04 15:26:23 +00005682 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005683#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005684}
5685#endif /* WEXITSTATUS */
5686
5687#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005690Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005692
5693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005694posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005695{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005696#ifdef UNION_WAIT
5697 union wait status;
5698#define status_i (status.w_status)
5699#else
5700 int status;
5701#define status_i status
5702#endif
5703 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005704
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005705 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005706 {
5707 return NULL;
5708 }
Tim Peters5aa91602002-01-30 05:46:57 +00005709
Guido van Rossumc9641791998-08-04 15:26:23 +00005710 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005711#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005712}
5713#endif /* WTERMSIG */
5714
5715#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005716PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005717"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718Return the signal that stopped the process that provided\n\
5719the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005720
5721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005722posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005723{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005724#ifdef UNION_WAIT
5725 union wait status;
5726#define status_i (status.w_status)
5727#else
5728 int status;
5729#define status_i status
5730#endif
5731 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005732
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005733 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005734 {
5735 return NULL;
5736 }
Tim Peters5aa91602002-01-30 05:46:57 +00005737
Guido van Rossumc9641791998-08-04 15:26:23 +00005738 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005739#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005740}
5741#endif /* WSTOPSIG */
5742
5743#endif /* HAVE_SYS_WAIT_H */
5744
5745
Guido van Rossum94f6f721999-01-06 18:42:14 +00005746#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005747#ifdef _SCO_DS
5748/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5749 needed definitions in sys/statvfs.h */
5750#define _SVID3
5751#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005752#include <sys/statvfs.h>
5753
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005754static PyObject*
5755_pystatvfs_fromstructstatvfs(struct statvfs st) {
5756 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5757 if (v == NULL)
5758 return NULL;
5759
5760#if !defined(HAVE_LARGEFILE_SUPPORT)
5761 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5762 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5763 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5764 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5765 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5766 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5767 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5768 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5769 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5770 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5771#else
5772 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5773 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005774 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005775 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005776 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005777 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005778 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005779 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005780 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005781 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005782 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005783 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005784 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005785 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005786 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5787 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5788#endif
5789
5790 return v;
5791}
5792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005794"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005795Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005796
5797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005798posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005799{
5800 int fd, res;
5801 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005802
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005803 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005804 return NULL;
5805 Py_BEGIN_ALLOW_THREADS
5806 res = fstatvfs(fd, &st);
5807 Py_END_ALLOW_THREADS
5808 if (res != 0)
5809 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005810
5811 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005812}
5813#endif /* HAVE_FSTATVFS */
5814
5815
5816#if defined(HAVE_STATVFS)
5817#include <sys/statvfs.h>
5818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005820"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005821Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005822
5823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005824posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005825{
5826 char *path;
5827 int res;
5828 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005829 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005830 return NULL;
5831 Py_BEGIN_ALLOW_THREADS
5832 res = statvfs(path, &st);
5833 Py_END_ALLOW_THREADS
5834 if (res != 0)
5835 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005836
5837 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005838}
5839#endif /* HAVE_STATVFS */
5840
5841
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005842#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005844"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005845Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005846The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005848
5849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005850posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005851{
5852 PyObject *result = NULL;
5853 char *dir = NULL;
5854 char *pfx = NULL;
5855 char *name;
5856
5857 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5858 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005859
5860 if (PyErr_Warn(PyExc_RuntimeWarning,
5861 "tempnam is a potential security risk to your program") < 0)
5862 return NULL;
5863
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005864#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005865 name = _tempnam(dir, pfx);
5866#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005867 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005868#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005869 if (name == NULL)
5870 return PyErr_NoMemory();
5871 result = PyString_FromString(name);
5872 free(name);
5873 return result;
5874}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005875#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005876
5877
5878#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005880"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005882
5883static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005884posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005885{
5886 FILE *fp;
5887
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005888 fp = tmpfile();
5889 if (fp == NULL)
5890 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005891 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005892}
5893#endif
5894
5895
5896#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005897PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005898"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005899Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005900
5901static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005902posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005903{
5904 char buffer[L_tmpnam];
5905 char *name;
5906
Skip Montanaro95618b52001-08-18 18:52:10 +00005907 if (PyErr_Warn(PyExc_RuntimeWarning,
5908 "tmpnam is a potential security risk to your program") < 0)
5909 return NULL;
5910
Greg Wardb48bc172000-03-01 21:51:56 +00005911#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005912 name = tmpnam_r(buffer);
5913#else
5914 name = tmpnam(buffer);
5915#endif
5916 if (name == NULL) {
5917 PyErr_SetObject(PyExc_OSError,
5918 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005919#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005920 "unexpected NULL from tmpnam_r"
5921#else
5922 "unexpected NULL from tmpnam"
5923#endif
5924 ));
5925 return NULL;
5926 }
5927 return PyString_FromString(buffer);
5928}
5929#endif
5930
5931
Fred Drakec9680921999-12-13 16:37:25 +00005932/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5933 * It maps strings representing configuration variable names to
5934 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005935 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005936 * rarely-used constants. There are three separate tables that use
5937 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005938 *
5939 * This code is always included, even if none of the interfaces that
5940 * need it are included. The #if hackery needed to avoid it would be
5941 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005942 */
5943struct constdef {
5944 char *name;
5945 long value;
5946};
5947
Fred Drake12c6e2d1999-12-14 21:25:03 +00005948static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005949conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5950 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005951{
5952 if (PyInt_Check(arg)) {
5953 *valuep = PyInt_AS_LONG(arg);
5954 return 1;
5955 }
5956 if (PyString_Check(arg)) {
5957 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005958 size_t lo = 0;
5959 size_t mid;
5960 size_t hi = tablesize;
5961 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005962 char *confname = PyString_AS_STRING(arg);
5963 while (lo < hi) {
5964 mid = (lo + hi) / 2;
5965 cmp = strcmp(confname, table[mid].name);
5966 if (cmp < 0)
5967 hi = mid;
5968 else if (cmp > 0)
5969 lo = mid + 1;
5970 else {
5971 *valuep = table[mid].value;
5972 return 1;
5973 }
5974 }
5975 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5976 }
5977 else
5978 PyErr_SetString(PyExc_TypeError,
5979 "configuration names must be strings or integers");
5980 return 0;
5981}
5982
5983
5984#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5985static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005986#ifdef _PC_ABI_AIO_XFER_MAX
5987 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5988#endif
5989#ifdef _PC_ABI_ASYNC_IO
5990 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5991#endif
Fred Drakec9680921999-12-13 16:37:25 +00005992#ifdef _PC_ASYNC_IO
5993 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5994#endif
5995#ifdef _PC_CHOWN_RESTRICTED
5996 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5997#endif
5998#ifdef _PC_FILESIZEBITS
5999 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6000#endif
6001#ifdef _PC_LAST
6002 {"PC_LAST", _PC_LAST},
6003#endif
6004#ifdef _PC_LINK_MAX
6005 {"PC_LINK_MAX", _PC_LINK_MAX},
6006#endif
6007#ifdef _PC_MAX_CANON
6008 {"PC_MAX_CANON", _PC_MAX_CANON},
6009#endif
6010#ifdef _PC_MAX_INPUT
6011 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6012#endif
6013#ifdef _PC_NAME_MAX
6014 {"PC_NAME_MAX", _PC_NAME_MAX},
6015#endif
6016#ifdef _PC_NO_TRUNC
6017 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6018#endif
6019#ifdef _PC_PATH_MAX
6020 {"PC_PATH_MAX", _PC_PATH_MAX},
6021#endif
6022#ifdef _PC_PIPE_BUF
6023 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6024#endif
6025#ifdef _PC_PRIO_IO
6026 {"PC_PRIO_IO", _PC_PRIO_IO},
6027#endif
6028#ifdef _PC_SOCK_MAXBUF
6029 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6030#endif
6031#ifdef _PC_SYNC_IO
6032 {"PC_SYNC_IO", _PC_SYNC_IO},
6033#endif
6034#ifdef _PC_VDISABLE
6035 {"PC_VDISABLE", _PC_VDISABLE},
6036#endif
6037};
6038
Fred Drakec9680921999-12-13 16:37:25 +00006039static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006040conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006041{
6042 return conv_confname(arg, valuep, posix_constants_pathconf,
6043 sizeof(posix_constants_pathconf)
6044 / sizeof(struct constdef));
6045}
6046#endif
6047
6048#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006051Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006053
6054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006055posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006056{
6057 PyObject *result = NULL;
6058 int name, fd;
6059
Fred Drake12c6e2d1999-12-14 21:25:03 +00006060 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6061 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006062 long limit;
6063
6064 errno = 0;
6065 limit = fpathconf(fd, name);
6066 if (limit == -1 && errno != 0)
6067 posix_error();
6068 else
6069 result = PyInt_FromLong(limit);
6070 }
6071 return result;
6072}
6073#endif
6074
6075
6076#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006077PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006078"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006079Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006081
6082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006084{
6085 PyObject *result = NULL;
6086 int name;
6087 char *path;
6088
6089 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6090 conv_path_confname, &name)) {
6091 long limit;
6092
6093 errno = 0;
6094 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006095 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006096 if (errno == EINVAL)
6097 /* could be a path or name problem */
6098 posix_error();
6099 else
6100 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006101 }
Fred Drakec9680921999-12-13 16:37:25 +00006102 else
6103 result = PyInt_FromLong(limit);
6104 }
6105 return result;
6106}
6107#endif
6108
6109#ifdef HAVE_CONFSTR
6110static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006111#ifdef _CS_ARCHITECTURE
6112 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6113#endif
6114#ifdef _CS_HOSTNAME
6115 {"CS_HOSTNAME", _CS_HOSTNAME},
6116#endif
6117#ifdef _CS_HW_PROVIDER
6118 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6119#endif
6120#ifdef _CS_HW_SERIAL
6121 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6122#endif
6123#ifdef _CS_INITTAB_NAME
6124 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6125#endif
Fred Drakec9680921999-12-13 16:37:25 +00006126#ifdef _CS_LFS64_CFLAGS
6127 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6128#endif
6129#ifdef _CS_LFS64_LDFLAGS
6130 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6131#endif
6132#ifdef _CS_LFS64_LIBS
6133 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6134#endif
6135#ifdef _CS_LFS64_LINTFLAGS
6136 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6137#endif
6138#ifdef _CS_LFS_CFLAGS
6139 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6140#endif
6141#ifdef _CS_LFS_LDFLAGS
6142 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6143#endif
6144#ifdef _CS_LFS_LIBS
6145 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6146#endif
6147#ifdef _CS_LFS_LINTFLAGS
6148 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6149#endif
Fred Draked86ed291999-12-15 15:34:33 +00006150#ifdef _CS_MACHINE
6151 {"CS_MACHINE", _CS_MACHINE},
6152#endif
Fred Drakec9680921999-12-13 16:37:25 +00006153#ifdef _CS_PATH
6154 {"CS_PATH", _CS_PATH},
6155#endif
Fred Draked86ed291999-12-15 15:34:33 +00006156#ifdef _CS_RELEASE
6157 {"CS_RELEASE", _CS_RELEASE},
6158#endif
6159#ifdef _CS_SRPC_DOMAIN
6160 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6161#endif
6162#ifdef _CS_SYSNAME
6163 {"CS_SYSNAME", _CS_SYSNAME},
6164#endif
6165#ifdef _CS_VERSION
6166 {"CS_VERSION", _CS_VERSION},
6167#endif
Fred Drakec9680921999-12-13 16:37:25 +00006168#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6169 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6170#endif
6171#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6172 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6173#endif
6174#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6175 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6176#endif
6177#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6178 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6179#endif
6180#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6181 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6182#endif
6183#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6184 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6185#endif
6186#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6187 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6188#endif
6189#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6190 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6191#endif
6192#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6193 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6194#endif
6195#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6196 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6197#endif
6198#ifdef _CS_XBS5_LP64_OFF64_LIBS
6199 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6200#endif
6201#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6202 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6203#endif
6204#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6205 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6206#endif
6207#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6208 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6209#endif
6210#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6211 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6212#endif
6213#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6214 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6215#endif
Fred Draked86ed291999-12-15 15:34:33 +00006216#ifdef _MIPS_CS_AVAIL_PROCESSORS
6217 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6218#endif
6219#ifdef _MIPS_CS_BASE
6220 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6221#endif
6222#ifdef _MIPS_CS_HOSTID
6223 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6224#endif
6225#ifdef _MIPS_CS_HW_NAME
6226 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6227#endif
6228#ifdef _MIPS_CS_NUM_PROCESSORS
6229 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6230#endif
6231#ifdef _MIPS_CS_OSREL_MAJ
6232 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6233#endif
6234#ifdef _MIPS_CS_OSREL_MIN
6235 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6236#endif
6237#ifdef _MIPS_CS_OSREL_PATCH
6238 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6239#endif
6240#ifdef _MIPS_CS_OS_NAME
6241 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6242#endif
6243#ifdef _MIPS_CS_OS_PROVIDER
6244 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6245#endif
6246#ifdef _MIPS_CS_PROCESSORS
6247 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6248#endif
6249#ifdef _MIPS_CS_SERIAL
6250 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6251#endif
6252#ifdef _MIPS_CS_VENDOR
6253 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6254#endif
Fred Drakec9680921999-12-13 16:37:25 +00006255};
6256
6257static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006258conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006259{
6260 return conv_confname(arg, valuep, posix_constants_confstr,
6261 sizeof(posix_constants_confstr)
6262 / sizeof(struct constdef));
6263}
6264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006266"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006268
6269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006270posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006271{
6272 PyObject *result = NULL;
6273 int name;
6274 char buffer[64];
6275
6276 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6277 int len = confstr(name, buffer, sizeof(buffer));
6278
Fred Drakec9680921999-12-13 16:37:25 +00006279 errno = 0;
6280 if (len == 0) {
6281 if (errno != 0)
6282 posix_error();
6283 else
6284 result = PyString_FromString("");
6285 }
6286 else {
6287 if (len >= sizeof(buffer)) {
6288 result = PyString_FromStringAndSize(NULL, len);
6289 if (result != NULL)
6290 confstr(name, PyString_AS_STRING(result), len+1);
6291 }
6292 else
6293 result = PyString_FromString(buffer);
6294 }
6295 }
6296 return result;
6297}
6298#endif
6299
6300
6301#ifdef HAVE_SYSCONF
6302static struct constdef posix_constants_sysconf[] = {
6303#ifdef _SC_2_CHAR_TERM
6304 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6305#endif
6306#ifdef _SC_2_C_BIND
6307 {"SC_2_C_BIND", _SC_2_C_BIND},
6308#endif
6309#ifdef _SC_2_C_DEV
6310 {"SC_2_C_DEV", _SC_2_C_DEV},
6311#endif
6312#ifdef _SC_2_C_VERSION
6313 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6314#endif
6315#ifdef _SC_2_FORT_DEV
6316 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6317#endif
6318#ifdef _SC_2_FORT_RUN
6319 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6320#endif
6321#ifdef _SC_2_LOCALEDEF
6322 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6323#endif
6324#ifdef _SC_2_SW_DEV
6325 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6326#endif
6327#ifdef _SC_2_UPE
6328 {"SC_2_UPE", _SC_2_UPE},
6329#endif
6330#ifdef _SC_2_VERSION
6331 {"SC_2_VERSION", _SC_2_VERSION},
6332#endif
Fred Draked86ed291999-12-15 15:34:33 +00006333#ifdef _SC_ABI_ASYNCHRONOUS_IO
6334 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6335#endif
6336#ifdef _SC_ACL
6337 {"SC_ACL", _SC_ACL},
6338#endif
Fred Drakec9680921999-12-13 16:37:25 +00006339#ifdef _SC_AIO_LISTIO_MAX
6340 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6341#endif
Fred Drakec9680921999-12-13 16:37:25 +00006342#ifdef _SC_AIO_MAX
6343 {"SC_AIO_MAX", _SC_AIO_MAX},
6344#endif
6345#ifdef _SC_AIO_PRIO_DELTA_MAX
6346 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6347#endif
6348#ifdef _SC_ARG_MAX
6349 {"SC_ARG_MAX", _SC_ARG_MAX},
6350#endif
6351#ifdef _SC_ASYNCHRONOUS_IO
6352 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6353#endif
6354#ifdef _SC_ATEXIT_MAX
6355 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6356#endif
Fred Draked86ed291999-12-15 15:34:33 +00006357#ifdef _SC_AUDIT
6358 {"SC_AUDIT", _SC_AUDIT},
6359#endif
Fred Drakec9680921999-12-13 16:37:25 +00006360#ifdef _SC_AVPHYS_PAGES
6361 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6362#endif
6363#ifdef _SC_BC_BASE_MAX
6364 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6365#endif
6366#ifdef _SC_BC_DIM_MAX
6367 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6368#endif
6369#ifdef _SC_BC_SCALE_MAX
6370 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6371#endif
6372#ifdef _SC_BC_STRING_MAX
6373 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6374#endif
Fred Draked86ed291999-12-15 15:34:33 +00006375#ifdef _SC_CAP
6376 {"SC_CAP", _SC_CAP},
6377#endif
Fred Drakec9680921999-12-13 16:37:25 +00006378#ifdef _SC_CHARCLASS_NAME_MAX
6379 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6380#endif
6381#ifdef _SC_CHAR_BIT
6382 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6383#endif
6384#ifdef _SC_CHAR_MAX
6385 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6386#endif
6387#ifdef _SC_CHAR_MIN
6388 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6389#endif
6390#ifdef _SC_CHILD_MAX
6391 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6392#endif
6393#ifdef _SC_CLK_TCK
6394 {"SC_CLK_TCK", _SC_CLK_TCK},
6395#endif
6396#ifdef _SC_COHER_BLKSZ
6397 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6398#endif
6399#ifdef _SC_COLL_WEIGHTS_MAX
6400 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6401#endif
6402#ifdef _SC_DCACHE_ASSOC
6403 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6404#endif
6405#ifdef _SC_DCACHE_BLKSZ
6406 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6407#endif
6408#ifdef _SC_DCACHE_LINESZ
6409 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6410#endif
6411#ifdef _SC_DCACHE_SZ
6412 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6413#endif
6414#ifdef _SC_DCACHE_TBLKSZ
6415 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6416#endif
6417#ifdef _SC_DELAYTIMER_MAX
6418 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6419#endif
6420#ifdef _SC_EQUIV_CLASS_MAX
6421 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6422#endif
6423#ifdef _SC_EXPR_NEST_MAX
6424 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6425#endif
6426#ifdef _SC_FSYNC
6427 {"SC_FSYNC", _SC_FSYNC},
6428#endif
6429#ifdef _SC_GETGR_R_SIZE_MAX
6430 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6431#endif
6432#ifdef _SC_GETPW_R_SIZE_MAX
6433 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6434#endif
6435#ifdef _SC_ICACHE_ASSOC
6436 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6437#endif
6438#ifdef _SC_ICACHE_BLKSZ
6439 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6440#endif
6441#ifdef _SC_ICACHE_LINESZ
6442 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6443#endif
6444#ifdef _SC_ICACHE_SZ
6445 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6446#endif
Fred Draked86ed291999-12-15 15:34:33 +00006447#ifdef _SC_INF
6448 {"SC_INF", _SC_INF},
6449#endif
Fred Drakec9680921999-12-13 16:37:25 +00006450#ifdef _SC_INT_MAX
6451 {"SC_INT_MAX", _SC_INT_MAX},
6452#endif
6453#ifdef _SC_INT_MIN
6454 {"SC_INT_MIN", _SC_INT_MIN},
6455#endif
6456#ifdef _SC_IOV_MAX
6457 {"SC_IOV_MAX", _SC_IOV_MAX},
6458#endif
Fred Draked86ed291999-12-15 15:34:33 +00006459#ifdef _SC_IP_SECOPTS
6460 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6461#endif
Fred Drakec9680921999-12-13 16:37:25 +00006462#ifdef _SC_JOB_CONTROL
6463 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6464#endif
Fred Draked86ed291999-12-15 15:34:33 +00006465#ifdef _SC_KERN_POINTERS
6466 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6467#endif
6468#ifdef _SC_KERN_SIM
6469 {"SC_KERN_SIM", _SC_KERN_SIM},
6470#endif
Fred Drakec9680921999-12-13 16:37:25 +00006471#ifdef _SC_LINE_MAX
6472 {"SC_LINE_MAX", _SC_LINE_MAX},
6473#endif
6474#ifdef _SC_LOGIN_NAME_MAX
6475 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6476#endif
6477#ifdef _SC_LOGNAME_MAX
6478 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6479#endif
6480#ifdef _SC_LONG_BIT
6481 {"SC_LONG_BIT", _SC_LONG_BIT},
6482#endif
Fred Draked86ed291999-12-15 15:34:33 +00006483#ifdef _SC_MAC
6484 {"SC_MAC", _SC_MAC},
6485#endif
Fred Drakec9680921999-12-13 16:37:25 +00006486#ifdef _SC_MAPPED_FILES
6487 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6488#endif
6489#ifdef _SC_MAXPID
6490 {"SC_MAXPID", _SC_MAXPID},
6491#endif
6492#ifdef _SC_MB_LEN_MAX
6493 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6494#endif
6495#ifdef _SC_MEMLOCK
6496 {"SC_MEMLOCK", _SC_MEMLOCK},
6497#endif
6498#ifdef _SC_MEMLOCK_RANGE
6499 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6500#endif
6501#ifdef _SC_MEMORY_PROTECTION
6502 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6503#endif
6504#ifdef _SC_MESSAGE_PASSING
6505 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6506#endif
Fred Draked86ed291999-12-15 15:34:33 +00006507#ifdef _SC_MMAP_FIXED_ALIGNMENT
6508 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6509#endif
Fred Drakec9680921999-12-13 16:37:25 +00006510#ifdef _SC_MQ_OPEN_MAX
6511 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6512#endif
6513#ifdef _SC_MQ_PRIO_MAX
6514 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6515#endif
Fred Draked86ed291999-12-15 15:34:33 +00006516#ifdef _SC_NACLS_MAX
6517 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6518#endif
Fred Drakec9680921999-12-13 16:37:25 +00006519#ifdef _SC_NGROUPS_MAX
6520 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6521#endif
6522#ifdef _SC_NL_ARGMAX
6523 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6524#endif
6525#ifdef _SC_NL_LANGMAX
6526 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6527#endif
6528#ifdef _SC_NL_MSGMAX
6529 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6530#endif
6531#ifdef _SC_NL_NMAX
6532 {"SC_NL_NMAX", _SC_NL_NMAX},
6533#endif
6534#ifdef _SC_NL_SETMAX
6535 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6536#endif
6537#ifdef _SC_NL_TEXTMAX
6538 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6539#endif
6540#ifdef _SC_NPROCESSORS_CONF
6541 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6542#endif
6543#ifdef _SC_NPROCESSORS_ONLN
6544 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6545#endif
Fred Draked86ed291999-12-15 15:34:33 +00006546#ifdef _SC_NPROC_CONF
6547 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6548#endif
6549#ifdef _SC_NPROC_ONLN
6550 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6551#endif
Fred Drakec9680921999-12-13 16:37:25 +00006552#ifdef _SC_NZERO
6553 {"SC_NZERO", _SC_NZERO},
6554#endif
6555#ifdef _SC_OPEN_MAX
6556 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6557#endif
6558#ifdef _SC_PAGESIZE
6559 {"SC_PAGESIZE", _SC_PAGESIZE},
6560#endif
6561#ifdef _SC_PAGE_SIZE
6562 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6563#endif
6564#ifdef _SC_PASS_MAX
6565 {"SC_PASS_MAX", _SC_PASS_MAX},
6566#endif
6567#ifdef _SC_PHYS_PAGES
6568 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6569#endif
6570#ifdef _SC_PII
6571 {"SC_PII", _SC_PII},
6572#endif
6573#ifdef _SC_PII_INTERNET
6574 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6575#endif
6576#ifdef _SC_PII_INTERNET_DGRAM
6577 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6578#endif
6579#ifdef _SC_PII_INTERNET_STREAM
6580 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6581#endif
6582#ifdef _SC_PII_OSI
6583 {"SC_PII_OSI", _SC_PII_OSI},
6584#endif
6585#ifdef _SC_PII_OSI_CLTS
6586 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6587#endif
6588#ifdef _SC_PII_OSI_COTS
6589 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6590#endif
6591#ifdef _SC_PII_OSI_M
6592 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6593#endif
6594#ifdef _SC_PII_SOCKET
6595 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6596#endif
6597#ifdef _SC_PII_XTI
6598 {"SC_PII_XTI", _SC_PII_XTI},
6599#endif
6600#ifdef _SC_POLL
6601 {"SC_POLL", _SC_POLL},
6602#endif
6603#ifdef _SC_PRIORITIZED_IO
6604 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6605#endif
6606#ifdef _SC_PRIORITY_SCHEDULING
6607 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6608#endif
6609#ifdef _SC_REALTIME_SIGNALS
6610 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6611#endif
6612#ifdef _SC_RE_DUP_MAX
6613 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6614#endif
6615#ifdef _SC_RTSIG_MAX
6616 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6617#endif
6618#ifdef _SC_SAVED_IDS
6619 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6620#endif
6621#ifdef _SC_SCHAR_MAX
6622 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6623#endif
6624#ifdef _SC_SCHAR_MIN
6625 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6626#endif
6627#ifdef _SC_SELECT
6628 {"SC_SELECT", _SC_SELECT},
6629#endif
6630#ifdef _SC_SEMAPHORES
6631 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6632#endif
6633#ifdef _SC_SEM_NSEMS_MAX
6634 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6635#endif
6636#ifdef _SC_SEM_VALUE_MAX
6637 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6638#endif
6639#ifdef _SC_SHARED_MEMORY_OBJECTS
6640 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6641#endif
6642#ifdef _SC_SHRT_MAX
6643 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6644#endif
6645#ifdef _SC_SHRT_MIN
6646 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6647#endif
6648#ifdef _SC_SIGQUEUE_MAX
6649 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6650#endif
6651#ifdef _SC_SIGRT_MAX
6652 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6653#endif
6654#ifdef _SC_SIGRT_MIN
6655 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6656#endif
Fred Draked86ed291999-12-15 15:34:33 +00006657#ifdef _SC_SOFTPOWER
6658 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6659#endif
Fred Drakec9680921999-12-13 16:37:25 +00006660#ifdef _SC_SPLIT_CACHE
6661 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6662#endif
6663#ifdef _SC_SSIZE_MAX
6664 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6665#endif
6666#ifdef _SC_STACK_PROT
6667 {"SC_STACK_PROT", _SC_STACK_PROT},
6668#endif
6669#ifdef _SC_STREAM_MAX
6670 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6671#endif
6672#ifdef _SC_SYNCHRONIZED_IO
6673 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6674#endif
6675#ifdef _SC_THREADS
6676 {"SC_THREADS", _SC_THREADS},
6677#endif
6678#ifdef _SC_THREAD_ATTR_STACKADDR
6679 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6680#endif
6681#ifdef _SC_THREAD_ATTR_STACKSIZE
6682 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6683#endif
6684#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6685 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6686#endif
6687#ifdef _SC_THREAD_KEYS_MAX
6688 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6689#endif
6690#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6691 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6692#endif
6693#ifdef _SC_THREAD_PRIO_INHERIT
6694 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6695#endif
6696#ifdef _SC_THREAD_PRIO_PROTECT
6697 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6698#endif
6699#ifdef _SC_THREAD_PROCESS_SHARED
6700 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6701#endif
6702#ifdef _SC_THREAD_SAFE_FUNCTIONS
6703 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6704#endif
6705#ifdef _SC_THREAD_STACK_MIN
6706 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6707#endif
6708#ifdef _SC_THREAD_THREADS_MAX
6709 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6710#endif
6711#ifdef _SC_TIMERS
6712 {"SC_TIMERS", _SC_TIMERS},
6713#endif
6714#ifdef _SC_TIMER_MAX
6715 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6716#endif
6717#ifdef _SC_TTY_NAME_MAX
6718 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6719#endif
6720#ifdef _SC_TZNAME_MAX
6721 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6722#endif
6723#ifdef _SC_T_IOV_MAX
6724 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6725#endif
6726#ifdef _SC_UCHAR_MAX
6727 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6728#endif
6729#ifdef _SC_UINT_MAX
6730 {"SC_UINT_MAX", _SC_UINT_MAX},
6731#endif
6732#ifdef _SC_UIO_MAXIOV
6733 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6734#endif
6735#ifdef _SC_ULONG_MAX
6736 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6737#endif
6738#ifdef _SC_USHRT_MAX
6739 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6740#endif
6741#ifdef _SC_VERSION
6742 {"SC_VERSION", _SC_VERSION},
6743#endif
6744#ifdef _SC_WORD_BIT
6745 {"SC_WORD_BIT", _SC_WORD_BIT},
6746#endif
6747#ifdef _SC_XBS5_ILP32_OFF32
6748 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6749#endif
6750#ifdef _SC_XBS5_ILP32_OFFBIG
6751 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6752#endif
6753#ifdef _SC_XBS5_LP64_OFF64
6754 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6755#endif
6756#ifdef _SC_XBS5_LPBIG_OFFBIG
6757 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6758#endif
6759#ifdef _SC_XOPEN_CRYPT
6760 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6761#endif
6762#ifdef _SC_XOPEN_ENH_I18N
6763 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6764#endif
6765#ifdef _SC_XOPEN_LEGACY
6766 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6767#endif
6768#ifdef _SC_XOPEN_REALTIME
6769 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6770#endif
6771#ifdef _SC_XOPEN_REALTIME_THREADS
6772 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6773#endif
6774#ifdef _SC_XOPEN_SHM
6775 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6776#endif
6777#ifdef _SC_XOPEN_UNIX
6778 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6779#endif
6780#ifdef _SC_XOPEN_VERSION
6781 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6782#endif
6783#ifdef _SC_XOPEN_XCU_VERSION
6784 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6785#endif
6786#ifdef _SC_XOPEN_XPG2
6787 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6788#endif
6789#ifdef _SC_XOPEN_XPG3
6790 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6791#endif
6792#ifdef _SC_XOPEN_XPG4
6793 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6794#endif
6795};
6796
6797static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006798conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006799{
6800 return conv_confname(arg, valuep, posix_constants_sysconf,
6801 sizeof(posix_constants_sysconf)
6802 / sizeof(struct constdef));
6803}
6804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006805PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006806"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006807Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006808
6809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006810posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006811{
6812 PyObject *result = NULL;
6813 int name;
6814
6815 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6816 int value;
6817
6818 errno = 0;
6819 value = sysconf(name);
6820 if (value == -1 && errno != 0)
6821 posix_error();
6822 else
6823 result = PyInt_FromLong(value);
6824 }
6825 return result;
6826}
6827#endif
6828
6829
Fred Drakebec628d1999-12-15 18:31:10 +00006830/* This code is used to ensure that the tables of configuration value names
6831 * are in sorted order as required by conv_confname(), and also to build the
6832 * the exported dictionaries that are used to publish information about the
6833 * names available on the host platform.
6834 *
6835 * Sorting the table at runtime ensures that the table is properly ordered
6836 * when used, even for platforms we're not able to test on. It also makes
6837 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006838 */
Fred Drakebec628d1999-12-15 18:31:10 +00006839
6840static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006841cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006842{
6843 const struct constdef *c1 =
6844 (const struct constdef *) v1;
6845 const struct constdef *c2 =
6846 (const struct constdef *) v2;
6847
6848 return strcmp(c1->name, c2->name);
6849}
6850
6851static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006852setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006853 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006854{
Fred Drakebec628d1999-12-15 18:31:10 +00006855 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006856 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006857
6858 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6859 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006860 if (d == NULL)
6861 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006862
Barry Warsaw3155db32000-04-13 15:20:40 +00006863 for (i=0; i < tablesize; ++i) {
6864 PyObject *o = PyInt_FromLong(table[i].value);
6865 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6866 Py_XDECREF(o);
6867 Py_DECREF(d);
6868 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006869 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006870 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006871 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006872 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006873}
6874
Fred Drakebec628d1999-12-15 18:31:10 +00006875/* Return -1 on failure, 0 on success. */
6876static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006877setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006878{
6879#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006880 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006881 sizeof(posix_constants_pathconf)
6882 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006883 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006884 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006885#endif
6886#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006887 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006888 sizeof(posix_constants_confstr)
6889 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006890 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006891 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006892#endif
6893#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006894 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006895 sizeof(posix_constants_sysconf)
6896 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006897 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006898 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006899#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006900 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006901}
Fred Draked86ed291999-12-15 15:34:33 +00006902
6903
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006904PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006905"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006906Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006907in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006908
6909static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006910posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006911{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006912 abort();
6913 /*NOTREACHED*/
6914 Py_FatalError("abort() called from Python code didn't abort!");
6915 return NULL;
6916}
Fred Drakebec628d1999-12-15 18:31:10 +00006917
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006918#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006919PyDoc_STRVAR(win32_startfile__doc__,
6920"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006921\n\
6922This acts like double-clicking the file in Explorer, or giving the file\n\
6923name as an argument to the DOS \"start\" command: the file is opened\n\
6924with whatever application (if any) its extension is associated.\n\
6925\n\
6926startfile returns as soon as the associated application is launched.\n\
6927There is no option to wait for the application to close, and no way\n\
6928to retrieve the application's exit status.\n\
6929\n\
6930The filepath is relative to the current directory. If you want to use\n\
6931an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006932the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006933
6934static PyObject *
6935win32_startfile(PyObject *self, PyObject *args)
6936{
6937 char *filepath;
6938 HINSTANCE rc;
6939 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6940 return NULL;
6941 Py_BEGIN_ALLOW_THREADS
6942 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6943 Py_END_ALLOW_THREADS
6944 if (rc <= (HINSTANCE)32)
6945 return win32_error("startfile", filepath);
6946 Py_INCREF(Py_None);
6947 return Py_None;
6948}
6949#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006950
Martin v. Löwis438b5342002-12-27 10:16:42 +00006951#ifdef HAVE_GETLOADAVG
6952PyDoc_STRVAR(posix_getloadavg__doc__,
6953"getloadavg() -> (float, float, float)\n\n\
6954Return the number of processes in the system run queue averaged over\n\
6955the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6956was unobtainable");
6957
6958static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006959posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006960{
6961 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006962 if (getloadavg(loadavg, 3)!=3) {
6963 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6964 return NULL;
6965 } else
6966 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6967}
6968#endif
6969
6970
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006971static PyMethodDef posix_methods[] = {
6972 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6973#ifdef HAVE_TTYNAME
6974 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6975#endif
6976 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6977 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006978#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006979 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006980#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006981#ifdef HAVE_LCHOWN
6982 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6983#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006984#ifdef HAVE_CHROOT
6985 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6986#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006987#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006988 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006989#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006990#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006991 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006992#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006993 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006994#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006995#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006996#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006997 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006998#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006999 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7000 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7001 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007002#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007003 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007004#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007005#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007006 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007007#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007008 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7009 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7010 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007011 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007012#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007013 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007014#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007015#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007016 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007017#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007018 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007019#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007020 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007021#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007022 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7023 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7024 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007025#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007026 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007027#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007028 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007029#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007030 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7031 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007032#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007033#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007034 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7035 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007036#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007037#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007038 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007039#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007040#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007041 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007042#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007043#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007044 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007045#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007046#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007047 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007048#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007049#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007050 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007051#endif /* HAVE_GETEGID */
7052#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007053 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007054#endif /* HAVE_GETEUID */
7055#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007056 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007057#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007058#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007059 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007060#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007061 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007062#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007063 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007064#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007065#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007066 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007067#endif /* HAVE_GETPPID */
7068#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007069 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007070#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007071#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007072 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007073#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007074#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007076#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007077#ifdef HAVE_KILLPG
7078 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7079#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007080#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007081 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007082#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007083#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007084 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007085#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007086 {"popen2", win32_popen2, METH_VARARGS},
7087 {"popen3", win32_popen3, METH_VARARGS},
7088 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007089 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007090#else
7091#if defined(PYOS_OS2) && defined(PYCC_GCC)
7092 {"popen2", os2emx_popen2, METH_VARARGS},
7093 {"popen3", os2emx_popen3, METH_VARARGS},
7094 {"popen4", os2emx_popen4, METH_VARARGS},
7095#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007096#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007097#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007098#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007099 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007100#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007101#ifdef HAVE_SETEUID
7102 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7103#endif /* HAVE_SETEUID */
7104#ifdef HAVE_SETEGID
7105 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7106#endif /* HAVE_SETEGID */
7107#ifdef HAVE_SETREUID
7108 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7109#endif /* HAVE_SETREUID */
7110#ifdef HAVE_SETREGID
7111 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7112#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007113#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007114 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007115#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007116#ifdef HAVE_SETGROUPS
7117 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7118#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007119#ifdef HAVE_GETPGID
7120 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7121#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007122#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007123 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007124#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007125#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007126 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007127#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007128#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007129 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007130#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007131#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007132 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007133#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007134#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007135 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007136#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007137#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007138 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007139#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007140#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007141 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007142#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007143 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7144 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7145 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7146 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7147 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7148 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7149 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7150 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7151 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007152 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007153#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007154 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007155#endif
7156#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007157 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007158#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007159#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007160 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7161#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007162#ifdef HAVE_DEVICE_MACROS
7163 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7164 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7165 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7166#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007167#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007168 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007169#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007170#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007172#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007173#ifdef HAVE_UNSETENV
7174 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7175#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007176#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007177 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007178#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007179#ifdef HAVE_FCHDIR
7180 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7181#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007182#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007183 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007184#endif
7185#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007186 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007187#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007188#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007189#ifdef WCOREDUMP
7190 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7191#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007192#ifdef WIFCONTINUED
7193 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7194#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007195#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007196 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007197#endif /* WIFSTOPPED */
7198#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007199 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007200#endif /* WIFSIGNALED */
7201#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007202 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007203#endif /* WIFEXITED */
7204#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007205 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007206#endif /* WEXITSTATUS */
7207#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007208 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007209#endif /* WTERMSIG */
7210#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007211 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007212#endif /* WSTOPSIG */
7213#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007214#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007216#endif
7217#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007218 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007219#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007220#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007221 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007222#endif
7223#ifdef HAVE_TEMPNAM
7224 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7225#endif
7226#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007227 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007228#endif
Fred Drakec9680921999-12-13 16:37:25 +00007229#ifdef HAVE_CONFSTR
7230 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7231#endif
7232#ifdef HAVE_SYSCONF
7233 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7234#endif
7235#ifdef HAVE_FPATHCONF
7236 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7237#endif
7238#ifdef HAVE_PATHCONF
7239 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7240#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007241 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007242#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007243 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7244#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007245#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007246 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007247#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007248 {NULL, NULL} /* Sentinel */
7249};
7250
7251
Barry Warsaw4a342091996-12-19 23:50:02 +00007252static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007253ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007254{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007255 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007256}
7257
Guido van Rossumd48f2521997-12-05 22:19:34 +00007258#if defined(PYOS_OS2)
7259/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007260static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007261{
7262 APIRET rc;
7263 ULONG values[QSV_MAX+1];
7264 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007265 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007266
7267 Py_BEGIN_ALLOW_THREADS
7268 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7269 Py_END_ALLOW_THREADS
7270
7271 if (rc != NO_ERROR) {
7272 os2_error(rc);
7273 return -1;
7274 }
7275
Fred Drake4d1e64b2002-04-15 19:40:07 +00007276 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7277 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7278 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7279 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7280 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7281 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7282 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007283
7284 switch (values[QSV_VERSION_MINOR]) {
7285 case 0: ver = "2.00"; break;
7286 case 10: ver = "2.10"; break;
7287 case 11: ver = "2.11"; break;
7288 case 30: ver = "3.00"; break;
7289 case 40: ver = "4.00"; break;
7290 case 50: ver = "5.00"; break;
7291 default:
Tim Peters885d4572001-11-28 20:27:42 +00007292 PyOS_snprintf(tmp, sizeof(tmp),
7293 "%d-%d", values[QSV_VERSION_MAJOR],
7294 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007295 ver = &tmp[0];
7296 }
7297
7298 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007299 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007300 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007301
7302 /* Add Indicator of Which Drive was Used to Boot the System */
7303 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7304 tmp[1] = ':';
7305 tmp[2] = '\0';
7306
Fred Drake4d1e64b2002-04-15 19:40:07 +00007307 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007308}
7309#endif
7310
Barry Warsaw4a342091996-12-19 23:50:02 +00007311static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007312all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007313{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007314#ifdef F_OK
7315 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007316#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007317#ifdef R_OK
7318 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007319#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007320#ifdef W_OK
7321 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007322#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007323#ifdef X_OK
7324 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007325#endif
Fred Drakec9680921999-12-13 16:37:25 +00007326#ifdef NGROUPS_MAX
7327 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7328#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007329#ifdef TMP_MAX
7330 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7331#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007332#ifdef WCONTINUED
7333 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7334#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007335#ifdef WNOHANG
7336 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007337#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007338#ifdef WUNTRACED
7339 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7340#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007341#ifdef O_RDONLY
7342 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7343#endif
7344#ifdef O_WRONLY
7345 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7346#endif
7347#ifdef O_RDWR
7348 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7349#endif
7350#ifdef O_NDELAY
7351 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7352#endif
7353#ifdef O_NONBLOCK
7354 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7355#endif
7356#ifdef O_APPEND
7357 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7358#endif
7359#ifdef O_DSYNC
7360 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7361#endif
7362#ifdef O_RSYNC
7363 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7364#endif
7365#ifdef O_SYNC
7366 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7367#endif
7368#ifdef O_NOCTTY
7369 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7370#endif
7371#ifdef O_CREAT
7372 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7373#endif
7374#ifdef O_EXCL
7375 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7376#endif
7377#ifdef O_TRUNC
7378 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7379#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007380#ifdef O_BINARY
7381 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7382#endif
7383#ifdef O_TEXT
7384 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7385#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007386#ifdef O_LARGEFILE
7387 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7388#endif
7389
Tim Peters5aa91602002-01-30 05:46:57 +00007390/* MS Windows */
7391#ifdef O_NOINHERIT
7392 /* Don't inherit in child processes. */
7393 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7394#endif
7395#ifdef _O_SHORT_LIVED
7396 /* Optimize for short life (keep in memory). */
7397 /* MS forgot to define this one with a non-underscore form too. */
7398 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7399#endif
7400#ifdef O_TEMPORARY
7401 /* Automatically delete when last handle is closed. */
7402 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7403#endif
7404#ifdef O_RANDOM
7405 /* Optimize for random access. */
7406 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7407#endif
7408#ifdef O_SEQUENTIAL
7409 /* Optimize for sequential access. */
7410 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7411#endif
7412
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007413/* GNU extensions. */
7414#ifdef O_DIRECT
7415 /* Direct disk access. */
7416 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7417#endif
7418#ifdef O_DIRECTORY
7419 /* Must be a directory. */
7420 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7421#endif
7422#ifdef O_NOFOLLOW
7423 /* Do not follow links. */
7424 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7425#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007426
Barry Warsaw5676bd12003-01-07 20:57:09 +00007427 /* These come from sysexits.h */
7428#ifdef EX_OK
7429 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007430#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007431#ifdef EX_USAGE
7432 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007433#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007434#ifdef EX_DATAERR
7435 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007436#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007437#ifdef EX_NOINPUT
7438 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007439#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007440#ifdef EX_NOUSER
7441 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007442#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007443#ifdef EX_NOHOST
7444 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007445#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007446#ifdef EX_UNAVAILABLE
7447 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007448#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007449#ifdef EX_SOFTWARE
7450 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007451#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007452#ifdef EX_OSERR
7453 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007454#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007455#ifdef EX_OSFILE
7456 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007457#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007458#ifdef EX_CANTCREAT
7459 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007460#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007461#ifdef EX_IOERR
7462 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007463#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007464#ifdef EX_TEMPFAIL
7465 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007466#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007467#ifdef EX_PROTOCOL
7468 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007469#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007470#ifdef EX_NOPERM
7471 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007472#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007473#ifdef EX_CONFIG
7474 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007475#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007476#ifdef EX_NOTFOUND
7477 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007478#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007479
Guido van Rossum246bc171999-02-01 23:54:31 +00007480#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007481#if defined(PYOS_OS2) && defined(PYCC_GCC)
7482 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7483 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7484 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7485 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7486 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7487 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7488 if (ins(d, "P_PM", (long)P_PM)) return -1;
7489 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7490 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7491 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7492 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7493 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7494 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7495 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7496 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7497 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7498 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7499 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7500 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7501 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7502#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007503 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7504 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7505 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7506 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7507 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007508#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007509#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007510
Guido van Rossumd48f2521997-12-05 22:19:34 +00007511#if defined(PYOS_OS2)
7512 if (insertvalues(d)) return -1;
7513#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007514 return 0;
7515}
7516
7517
Tim Peters5aa91602002-01-30 05:46:57 +00007518#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007519#define INITFUNC initnt
7520#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007521
7522#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007523#define INITFUNC initos2
7524#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007525
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007526#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007527#define INITFUNC initposix
7528#define MODNAME "posix"
7529#endif
7530
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007531PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007532INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007533{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007534 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007535
Fred Drake4d1e64b2002-04-15 19:40:07 +00007536 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007537 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007538 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007539
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007540 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007541 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007542 Py_XINCREF(v);
7543 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007544 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007545 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007546
Fred Drake4d1e64b2002-04-15 19:40:07 +00007547 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007548 return;
7549
Fred Drake4d1e64b2002-04-15 19:40:07 +00007550 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007551 return;
7552
Fred Drake4d1e64b2002-04-15 19:40:07 +00007553 Py_INCREF(PyExc_OSError);
7554 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007555
Guido van Rossumb3d39562000-01-31 18:41:26 +00007556#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007557 if (posix_putenv_garbage == NULL)
7558 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007559#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007560
Guido van Rossum14648392001-12-08 18:02:58 +00007561 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007562 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7563 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7564 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007565 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007566 structseq_new = StatResultType.tp_new;
7567 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007568 Py_INCREF((PyObject*) &StatResultType);
7569 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007570
Guido van Rossum14648392001-12-08 18:02:58 +00007571 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007572 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007573 Py_INCREF((PyObject*) &StatVFSResultType);
7574 PyModule_AddObject(m, "statvfs_result",
7575 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007576}