blob: ab4992ec144d66cd4e19de14e798abd80ae5af5e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
20# include <ctype.h> /* tolower() */
21# include <descrip.h> /* string descriptors */
22# include <dvidef.h> /* DVI$_name */
23# include <file.h> /* -> O_RDWR */
24# include <jpidef.h> /* JPI$_name */
25# include <lib$routines.h> /* LIB$name */
26# include <ots$routines.h> /* OTS$name */
27# include <ssdef.h> /* SS$_name */
28# include <unixio.h>
29# include <unixlib.h>
30# include <stat.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000031# include <wait.h> /* define wait() */
32#endif /* defined(__VMS) */
33
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000035"This module provides access to operating system functionality that is\n\
36standardized by the C Standard and the POSIX standard (a thinly\n\
37disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000038corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000040#ifndef Py_USING_UNICODE
41/* This is used in signatures of functions. */
42#define Py_UNICODE void
43#endif
44
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYOS_OS2)
46#define INCL_DOS
47#define INCL_DOSERRORS
48#define INCL_DOSPROCESS
49#define INCL_NOPMAPI
50#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000051#if defined(PYCC_GCC)
52#include <ctype.h>
53#include <io.h>
54#include <stdio.h>
55#include <process.h>
56#include "osdefs.h"
57#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000058#endif
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#include <sys/types.h>
61#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062
Guido van Rossum36bc6801995-06-14 22:54:23 +000063#ifdef HAVE_SYS_WAIT_H
64#include <sys/wait.h> /* For WNOHANG */
65#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma376cc51996-12-05 23:43:35 +000067#ifdef HAVE_SIGNAL_H
68#include <signal.h>
69#endif
70
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#ifdef HAVE_FCNTL_H
72#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Guido van Rossuma6535fd2001-10-18 19:44:10 +000075#ifdef HAVE_GRP_H
76#include <grp.h>
77#endif
78
Barry Warsaw5676bd12003-01-07 20:57:09 +000079#ifdef HAVE_SYSEXITS_H
80#include <sysexits.h>
81#endif /* HAVE_SYSEXITS_H */
82
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000084/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000085#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000086#include <process.h>
87#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000088#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#define HAVE_GETCWD 1
90#define HAVE_OPENDIR 1
91#define HAVE_SYSTEM 1
92#if defined(__OS2__)
93#define HAVE_EXECV 1
94#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000095#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000096#include <process.h>
97#else
98#ifdef __BORLANDC__ /* Borland compiler */
99#define HAVE_EXECV 1
100#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_OPENDIR 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
105#define HAVE_WAIT 1
106#else
107#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000108#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000109#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#define HAVE_EXECV 1
111#define HAVE_PIPE 1
112#define HAVE_POPEN 1
113#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000114#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000115#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000116#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
117/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#else /* all other compilers */
119/* Unix functions that the configure script doesn't check for */
120#define HAVE_EXECV 1
121#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000122#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
123#define HAVE_FORK1 1
124#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_GETCWD 1
126#define HAVE_GETEGID 1
127#define HAVE_GETEUID 1
128#define HAVE_GETGID 1
129#define HAVE_GETPPID 1
130#define HAVE_GETUID 1
131#define HAVE_KILL 1
132#define HAVE_OPENDIR 1
133#define HAVE_PIPE 1
134#define HAVE_POPEN 1
135#define HAVE_SYSTEM 1
136#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000137#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000138#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#endif /* _MSC_VER */
140#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000141#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000145
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000146#if defined(sun) && !defined(__SVR4)
147/* SunOS 4.1.4 doesn't have prototypes for these: */
148extern int rename(const char *, const char *);
149extern int pclose(FILE *);
150extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000151extern int fsync(int);
152extern int lstat(const char *, struct stat *);
153extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000154#endif
155
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000156#if defined(__sgi)&&_COMPILER_VERSION>=700
157/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
158 (default) */
159extern char *ctermid_r(char *);
160#endif
161
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000162#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000164extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000166#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#endif
172#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int chdir(char *);
174extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int chdir(const char *);
177extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000179#ifdef __BORLANDC__
180extern int chmod(const char *, int);
181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000183#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chown(const char *, uid_t, gid_t);
185extern char *getcwd(char *, int);
186extern char *strerror(int);
187extern int link(const char *, const char *);
188extern int rename(const char *, const char *);
189extern int stat(const char *, struct stat *);
190extern int unlink(const char *);
191extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000194#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_UTIME_H
203#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000206#ifdef HAVE_SYS_UTIME_H
207#include <sys/utime.h>
208#define HAVE_UTIME_H /* pretend we do for the rest of this file */
209#endif /* HAVE_SYS_UTIME_H */
210
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_SYS_TIMES_H
212#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
215#ifdef HAVE_SYS_PARAM_H
216#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_UTSNAME_H
220#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#define NAMLEN(dirent) strlen((dirent)->d_name)
226#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000227#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#include <direct.h>
229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000232#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#endif
237#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <direct.h>
247#include <io.h>
248#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000249#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000250#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000252#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000253#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000254#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossumd48f2521997-12-05 22:19:34 +0000257#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260
Tim Petersbc2e10e2002-03-03 23:17:02 +0000261#ifndef MAXPATHLEN
262#define MAXPATHLEN 1024
263#endif /* MAXPATHLEN */
264
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000265#ifdef UNION_WAIT
266/* Emulate some macros on systems that have a union instead of macros */
267
268#ifndef WIFEXITED
269#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
270#endif
271
272#ifndef WEXITSTATUS
273#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
274#endif
275
276#ifndef WTERMSIG
277#define WTERMSIG(u_wait) ((u_wait).w_termsig)
278#endif
279
280#endif /* UNION_WAIT */
281
Greg Wardb48bc172000-03-01 21:51:56 +0000282/* Don't use the "_r" form if we don't need it (also, won't have a
283 prototype for it, at least on Solaris -- maybe others as well?). */
284#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
285#define USE_CTERMID_R
286#endif
287
288#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
289#define USE_TMPNAM_R
290#endif
291
Fred Drake699f3522000-06-29 21:12:41 +0000292/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000293#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000294#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000295# define STAT _stati64
296# define FSTAT _fstati64
297# define STRUCT_STAT struct _stati64
298#else
299# define STAT stat
300# define FSTAT fstat
301# define STRUCT_STAT struct stat
302#endif
303
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000304#if defined(MAJOR_IN_MKDEV)
305#include <sys/mkdev.h>
306#else
307#if defined(MAJOR_IN_SYSMACROS)
308#include <sys/sysmacros.h>
309#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000310#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
311#include <sys/mkdev.h>
312#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000313#endif
Fred Drake699f3522000-06-29 21:12:41 +0000314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000316#ifdef WITH_NEXT_FRAMEWORK
317/* On Darwin/MacOSX a shared library or framework has no access to
318** environ directly, we must obtain it with _NSGetEnviron().
319*/
320#include <crt_externs.h>
321static char **environ;
322#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000324#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000326#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000327/* add some values to provide a similar environment like POSIX */
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000328static
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000329void
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000330vms_add_posix_env(PyObject *d)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000331{
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000332 PyObject *o;
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000333 char* str;
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000334
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000335 str = getenv("LINES");
336 o = Py_BuildValue("s", str);
337 if (o != NULL) {
338 (void)PyDict_SetItemString(d, "LINES", o);
339 Py_DECREF(o);
340 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000341
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000342 str = getenv("COLUMNS");
343 o = Py_BuildValue("s", str);
344 if (o != NULL) {
345 (void)PyDict_SetItemString(d, "COLUMNS", o);
346 Py_DECREF(o);
347 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000348
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000349 str = getenv("USER");
350 o = Py_BuildValue("s", str);
351 if (o != NULL) {
352 (void)PyDict_SetItemString(d, "USERNAME", o);
353 Py_DECREF(o);
354 }
355 o = Py_BuildValue("s", str);
356 if (o != NULL) {
357 (void)PyDict_SetItemString(d, "LOGNAME", o);
358 Py_DECREF(o);
359 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000360
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000361 str = getenv("HOME");
362 o = Py_BuildValue("s", str);
363 if (o != NULL) {
364 (void)PyDict_SetItemString(d, "HOME", o);
365 Py_DECREF(o);
366 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000367
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000368 str = getenv("PATH");
369 o = Py_BuildValue("s", str);
370 if (o != NULL) {
371 (void)PyDict_SetItemString(d, "PATH", o);
372 Py_DECREF(o);
373 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000374 /* OS = "OpenVMS" */
375 o = PyString_FromString ("OpenVMS");
376 if (o != NULL) {
377 (void)PyDict_SetItemString(d, "OS", o);
378 Py_DECREF(o);
379 }
380}
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000381#endif /* __VMS */
382
Barry Warsaw53699e91996-12-10 23:23:01 +0000383static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000384convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385{
Barry Warsaw53699e91996-12-10 23:23:01 +0000386 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000388 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 if (d == NULL)
390 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000391#ifdef WITH_NEXT_FRAMEWORK
392 if (environ == NULL)
393 environ = *_NSGetEnviron();
394#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 if (environ == NULL)
396 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000399 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000400 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 char *p = strchr(*e, '=');
402 if (p == NULL)
403 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000404 k = PyString_FromStringAndSize(*e, (int)(p-*e));
405 if (k == NULL) {
406 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000408 }
409 v = PyString_FromString(p+1);
410 if (v == NULL) {
411 PyErr_Clear();
412 Py_DECREF(k);
413 continue;
414 }
415 if (PyDict_GetItem(d, k) == NULL) {
416 if (PyDict_SetItem(d, k, v) != 0)
417 PyErr_Clear();
418 }
419 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000420 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000422#if defined(__VMS)
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000423 vms_add_posix_env(d);
424#elif defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000425 {
426 APIRET rc;
427 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
428
429 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000430 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431 PyObject *v = PyString_FromString(buffer);
432 PyDict_SetItemString(d, "BEGINLIBPATH", v);
433 Py_DECREF(v);
434 }
435 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
436 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
437 PyObject *v = PyString_FromString(buffer);
438 PyDict_SetItemString(d, "ENDLIBPATH", v);
439 Py_DECREF(v);
440 }
441 }
442#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443 return d;
444}
445
446
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447/* Set a POSIX-specific error from errno, and return NULL */
448
Barry Warsawd58d7641998-07-23 16:14:40 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000451{
Barry Warsawca74da41999-02-09 19:31:45 +0000452 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453}
Barry Warsawd58d7641998-07-23 16:14:40 +0000454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000455posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000456{
Barry Warsawca74da41999-02-09 19:31:45 +0000457 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000458}
459
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462posix_error_with_unicode_filename(Py_UNICODE* name)
463{
464 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
465}
466#endif /* Py_WIN_WIDE_FILENAMES */
467
468
Mark Hammondef8b6542001-05-13 08:04:26 +0000469static PyObject *
470posix_error_with_allocated_filename(char* name)
471{
472 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
473 PyMem_Free(name);
474 return rc;
475}
476
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000477#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000478static PyObject *
479win32_error(char* function, char* filename)
480{
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 /* XXX We should pass the function name along in the future.
482 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000483 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000484 Windows error object, which is non-trivial.
485 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000486 errno = GetLastError();
487 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000488 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000489 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000490 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000491}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000492
493#ifdef Py_WIN_WIDE_FILENAMES
494static PyObject *
495win32_error_unicode(char* function, Py_UNICODE* filename)
496{
497 /* XXX - see win32_error for comments on 'function' */
498 errno = GetLastError();
499 if (filename)
500 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
501 else
502 return PyErr_SetFromWindowsErr(errno);
503}
504
505static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
506{
507 /* XXX Perhaps we should make this API an alias of
508 PyObject_Unicode() instead ?! */
509 if (PyUnicode_CheckExact(obj)) {
510 Py_INCREF(obj);
511 return obj;
512 }
513 if (PyUnicode_Check(obj)) {
514 /* For a Unicode subtype that's not a Unicode object,
515 return a true Unicode object with the same data. */
516 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
517 PyUnicode_GET_SIZE(obj));
518 }
519 return PyUnicode_FromEncodedObject(obj,
520 Py_FileSystemDefaultEncoding,
521 "strict");
522}
523
524#endif /* Py_WIN_WIDE_FILENAMES */
525
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000526#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528#if defined(PYOS_OS2)
529/**********************************************************************
530 * Helper Function to Trim and Format OS/2 Messages
531 **********************************************************************/
532 static void
533os2_formatmsg(char *msgbuf, int msglen, char *reason)
534{
535 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
536
537 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
538 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
539
540 while (lastc > msgbuf && isspace(*lastc))
541 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
542 }
543
544 /* Add Optional Reason Text */
545 if (reason) {
546 strcat(msgbuf, " : ");
547 strcat(msgbuf, reason);
548 }
549}
550
551/**********************************************************************
552 * Decode an OS/2 Operating System Error Code
553 *
554 * A convenience function to lookup an OS/2 error code and return a
555 * text message we can use to raise a Python exception.
556 *
557 * Notes:
558 * The messages for errors returned from the OS/2 kernel reside in
559 * the file OSO001.MSG in the \OS2 directory hierarchy.
560 *
561 **********************************************************************/
562 static char *
563os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
564{
565 APIRET rc;
566 ULONG msglen;
567
568 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
569 Py_BEGIN_ALLOW_THREADS
570 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
571 errorcode, "oso001.msg", &msglen);
572 Py_END_ALLOW_THREADS
573
574 if (rc == NO_ERROR)
575 os2_formatmsg(msgbuf, msglen, reason);
576 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000577 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000578 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000579
580 return msgbuf;
581}
582
583/* Set an OS/2-specific error and return NULL. OS/2 kernel
584 errors are not in a global variable e.g. 'errno' nor are
585 they congruent with posix error numbers. */
586
587static PyObject * os2_error(int code)
588{
589 char text[1024];
590 PyObject *v;
591
592 os2_strerror(text, sizeof(text), code, "");
593
594 v = Py_BuildValue("(is)", code, text);
595 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000596 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000597 Py_DECREF(v);
598 }
599 return NULL; /* Signal to Python that an Exception is Pending */
600}
601
602#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603
604/* POSIX generic methods */
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000607posix_fildes(PyObject *fdobj, int (*func)(int))
608{
609 int fd;
610 int res;
611 fd = PyObject_AsFileDescriptor(fdobj);
612 if (fd < 0)
613 return NULL;
614 Py_BEGIN_ALLOW_THREADS
615 res = (*func)(fd);
616 Py_END_ALLOW_THREADS
617 if (res < 0)
618 return posix_error();
619 Py_INCREF(Py_None);
620 return Py_None;
621}
Guido van Rossum21142a01999-01-08 21:05:37 +0000622
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000623#ifdef Py_WIN_WIDE_FILENAMES
624static int
625unicode_file_names(void)
626{
627 static int canusewide = -1;
628 if (canusewide == -1) {
629 /* As per doc for ::GetVersion(), this is the correct test for
630 the Windows NT family. */
631 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
632 }
633 return canusewide;
634}
635#endif
636
Guido van Rossum21142a01999-01-08 21:05:37 +0000637static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000638posix_1str(PyObject *args, char *format, int (*func)(const char*),
639 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640{
Mark Hammondef8b6542001-05-13 08:04:26 +0000641 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000643#ifdef Py_WIN_WIDE_FILENAMES
644 if (unicode_file_names()) {
645 PyUnicodeObject *po;
646 if (PyArg_ParseTuple(args, wformat, &po)) {
647 Py_BEGIN_ALLOW_THREADS
648 /* PyUnicode_AS_UNICODE OK without thread
649 lock as it is a simple dereference. */
650 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
651 Py_END_ALLOW_THREADS
652 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000653 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654 Py_INCREF(Py_None);
655 return Py_None;
656 }
657 /* Drop the argument parsing error as narrow
658 strings are also valid. */
659 PyErr_Clear();
660 }
661#else
662 /* Platforms that don't support Unicode filenames
663 shouldn't be passing these extra params */
664 assert(wformat==NULL && wfunc == NULL);
665#endif
666
Tim Peters5aa91602002-01-30 05:46:57 +0000667 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000670 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000671 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000672 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000673 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000674 return posix_error_with_allocated_filename(path1);
675 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000676 Py_INCREF(Py_None);
677 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678}
679
Barry Warsaw53699e91996-12-10 23:23:01 +0000680static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000681posix_2str(PyObject *args,
682 char *format,
683 int (*func)(const char *, const char *),
684 char *wformat,
685 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686{
Mark Hammondef8b6542001-05-13 08:04:26 +0000687 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000688 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000689#ifdef Py_WIN_WIDE_FILENAMES
690 if (unicode_file_names()) {
691 PyObject *po1;
692 PyObject *po2;
693 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
694 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
695 PyObject *wpath1;
696 PyObject *wpath2;
697 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
698 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
699 if (!wpath1 || !wpath2) {
700 Py_XDECREF(wpath1);
701 Py_XDECREF(wpath2);
702 return NULL;
703 }
704 Py_BEGIN_ALLOW_THREADS
705 /* PyUnicode_AS_UNICODE OK without thread
706 lock as it is a simple dereference. */
707 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
708 PyUnicode_AS_UNICODE(wpath2));
709 Py_END_ALLOW_THREADS
710 Py_XDECREF(wpath1);
711 Py_XDECREF(wpath2);
712 if (res != 0)
713 return posix_error();
714 Py_INCREF(Py_None);
715 return Py_None;
716 }
717 /* Else flow through as neither is Unicode. */
718 }
719 /* Drop the argument parsing error as narrow
720 strings are also valid. */
721 PyErr_Clear();
722 }
723#else
724 /* Platforms that don't support Unicode filenames
725 shouldn't be passing these extra params */
726 assert(wformat==NULL && wfunc == NULL);
727#endif
728
Mark Hammondef8b6542001-05-13 08:04:26 +0000729 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000730 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000731 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000733 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000734 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000735 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000736 PyMem_Free(path1);
737 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000738 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000739 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743}
744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000745PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000746"stat_result: Result from stat or lstat.\n\n\
747This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000748 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000749or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
750\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000751Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000752they are available as attributes only.\n\
753\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000754See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000755
756static PyStructSequence_Field stat_result_fields[] = {
757 {"st_mode", "protection bits"},
758 {"st_ino", "inode"},
759 {"st_dev", "device"},
760 {"st_nlink", "number of hard links"},
761 {"st_uid", "user ID of owner"},
762 {"st_gid", "group ID of owner"},
763 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000764 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
765 {NULL, "integer time of last access"},
766 {NULL, "integer time of last modification"},
767 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000768 {"st_atime", "time of last access"},
769 {"st_mtime", "time of last modification"},
770 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000771#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000772 {"st_blksize", "blocksize for filesystem I/O"},
773#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000774#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000775 {"st_blocks", "number of blocks allocated"},
776#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000777#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000778 {"st_rdev", "device type (if inode device)"},
779#endif
780 {0}
781};
782
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000783#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000784#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000785#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000786#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000787#endif
788
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000789#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000790#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
791#else
792#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
793#endif
794
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000795#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000796#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
797#else
798#define ST_RDEV_IDX ST_BLOCKS_IDX
799#endif
800
801static PyStructSequence_Desc stat_result_desc = {
802 "stat_result", /* name */
803 stat_result__doc__, /* doc */
804 stat_result_fields,
805 10
806};
807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000808PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000809"statvfs_result: Result from statvfs or fstatvfs.\n\n\
810This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000811 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000812or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000813\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000814See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000815
816static PyStructSequence_Field statvfs_result_fields[] = {
817 {"f_bsize", },
818 {"f_frsize", },
819 {"f_blocks", },
820 {"f_bfree", },
821 {"f_bavail", },
822 {"f_files", },
823 {"f_ffree", },
824 {"f_favail", },
825 {"f_flag", },
826 {"f_namemax",},
827 {0}
828};
829
830static PyStructSequence_Desc statvfs_result_desc = {
831 "statvfs_result", /* name */
832 statvfs_result__doc__, /* doc */
833 statvfs_result_fields,
834 10
835};
836
837static PyTypeObject StatResultType;
838static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000839static newfunc structseq_new;
840
841static PyObject *
842statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
843{
844 PyStructSequence *result;
845 int i;
846
847 result = (PyStructSequence*)structseq_new(type, args, kwds);
848 if (!result)
849 return NULL;
850 /* If we have been initialized from a tuple,
851 st_?time might be set to None. Initialize it
852 from the int slots. */
853 for (i = 7; i <= 9; i++) {
854 if (result->ob_item[i+3] == Py_None) {
855 Py_DECREF(Py_None);
856 Py_INCREF(result->ob_item[i]);
857 result->ob_item[i+3] = result->ob_item[i];
858 }
859 }
860 return (PyObject*)result;
861}
862
863
864
865/* If true, st_?time is float. */
866static int _stat_float_times = 0;
867
868PyDoc_STRVAR(stat_float_times__doc__,
869"stat_float_times([newval]) -> oldval\n\n\
870Determine whether os.[lf]stat represents time stamps as float objects.\n\
871If newval is True, future calls to stat() return floats, if it is False,\n\
872future calls return ints. \n\
873If newval is omitted, return the current setting.\n");
874
875static PyObject*
876stat_float_times(PyObject* self, PyObject *args)
877{
878 int newval = -1;
879 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
880 return NULL;
881 if (newval == -1)
882 /* Return old value */
883 return PyBool_FromLong(_stat_float_times);
884 _stat_float_times = newval;
885 Py_INCREF(Py_None);
886 return Py_None;
887}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000889static void
890fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
891{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000892 PyObject *fval,*ival;
893#if SIZEOF_TIME_T > SIZEOF_LONG
894 ival = PyLong_FromLongLong((LONG_LONG)sec);
895#else
896 ival = PyInt_FromLong((long)sec);
897#endif
898 if (_stat_float_times) {
899 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
900 } else {
901 fval = ival;
902 Py_INCREF(fval);
903 }
904 PyStructSequence_SET_ITEM(v, index, ival);
905 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000906}
907
Tim Peters5aa91602002-01-30 05:46:57 +0000908/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000909 (used by posix_stat() and posix_fstat()) */
910static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000911_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000912{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000913 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000914 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000915 if (v == NULL)
916 return NULL;
917
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000918 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000919#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000920 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000921 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000922#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000923 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000924#endif
925#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000926 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000927 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000928#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000929 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000930#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
932 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
933 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000934#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000935 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000936 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000937#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000939#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000940
941#ifdef HAVE_STAT_TV_NSEC
942 ansec = st.st_atim.tv_nsec;
943 mnsec = st.st_mtim.tv_nsec;
944 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000945#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000946 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000948 fill_time(v, 7, st.st_atime, ansec);
949 fill_time(v, 8, st.st_mtime, mnsec);
950 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000951
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000952#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000953 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000954 PyInt_FromLong((long)st.st_blksize));
955#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000956#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000957 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000958 PyInt_FromLong((long)st.st_blocks));
959#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000960#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000961 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
962 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000963#endif
964
965 if (PyErr_Occurred()) {
966 Py_DECREF(v);
967 return NULL;
968 }
969
970 return v;
971}
972
Barry Warsaw53699e91996-12-10 23:23:01 +0000973static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000974posix_do_stat(PyObject *self, PyObject *args,
975 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000976#ifdef __VMS
977 int (*statfunc)(const char *, STRUCT_STAT *, ...),
978#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000979 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000980#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000981 char *wformat,
982 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983{
Fred Drake699f3522000-06-29 21:12:41 +0000984 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000985 char *path = NULL; /* pass this to stat; do not free() it */
986 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000987 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000988
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000989#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000990 int pathlen;
991 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000992#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000993
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000994
995#ifdef Py_WIN_WIDE_FILENAMES
996 /* If on wide-character-capable OS see if argument
997 is Unicode and if so use wide API. */
998 if (unicode_file_names()) {
999 PyUnicodeObject *po;
1000 if (PyArg_ParseTuple(args, wformat, &po)) {
1001 Py_UNICODE wpath[MAX_PATH+1];
1002 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1003 /* the library call can blow up if the file name is too long! */
1004 if (pathlen > MAX_PATH) {
1005 errno = ENAMETOOLONG;
1006 return posix_error();
1007 }
1008 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1009 /* Remove trailing slash or backslash, unless it's the current
1010 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1011 */
1012 if (pathlen > 0 &&
1013 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1014 /* It does end with a slash -- exempt the root drive cases. */
1015 /* XXX UNC root drives should also be exempted? */
1016 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1017 /* leave it alone */;
1018 else {
1019 /* nuke the trailing backslash */
1020 wpath[pathlen-1] = L'\0';
1021 }
1022 }
1023 Py_BEGIN_ALLOW_THREADS
1024 /* PyUnicode_AS_UNICODE result OK without
1025 thread lock as it is a simple dereference. */
1026 res = wstatfunc(wpath, &st);
1027 Py_END_ALLOW_THREADS
1028 if (res != 0)
1029 return posix_error_with_unicode_filename(wpath);
1030 return _pystat_fromstructstat(st);
1031 }
1032 /* Drop the argument parsing error as narrow strings
1033 are also valid. */
1034 PyErr_Clear();
1035 }
1036#endif
1037
Tim Peters5aa91602002-01-30 05:46:57 +00001038 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001039 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001041 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001042
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001043#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001044 pathlen = strlen(path);
1045 /* the library call can blow up if the file name is too long! */
1046 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001047 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001048 errno = ENAMETOOLONG;
1049 return posix_error();
1050 }
1051
Tim Peters500bd032001-12-19 19:05:01 +00001052 /* Remove trailing slash or backslash, unless it's the current
1053 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1054 */
1055 if (pathlen > 0 &&
1056 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1057 /* It does end with a slash -- exempt the root drive cases. */
1058 /* XXX UNC root drives should also be exempted? */
1059 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1060 /* leave it alone */;
1061 else {
1062 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001063 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001064 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001065 path = pathcopy;
1066 }
1067 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001068#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001069
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001071 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001073 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001074 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001075
Tim Peters500bd032001-12-19 19:05:01 +00001076 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001077 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001078}
1079
1080
1081/* POSIX methods */
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001084"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001085Use the real uid/gid to test for access to a path. Note that most\n\
1086operations will use the effective uid/gid, therefore this routine can\n\
1087be used in a suid/sgid environment to test if the invoking user has the\n\
1088specified access to the path. The mode argument can be F_OK to test\n\
1089existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001090
1091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001092posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001093{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001094 char *path;
1095 int mode;
1096 int res;
1097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001099 return NULL;
1100 Py_BEGIN_ALLOW_THREADS
1101 res = access(path, mode);
1102 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001103 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001104}
1105
Guido van Rossumd371ff11999-01-25 16:12:23 +00001106#ifndef F_OK
1107#define F_OK 0
1108#endif
1109#ifndef R_OK
1110#define R_OK 4
1111#endif
1112#ifndef W_OK
1113#define W_OK 2
1114#endif
1115#ifndef X_OK
1116#define X_OK 1
1117#endif
1118
1119#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001120PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001121"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001123
1124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001126{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001127 int id;
1128 char *ret;
1129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001130 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001131 return NULL;
1132
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001133#if defined(__VMS)
1134 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1135 if (id == 0) {
1136 ret = ttyname();
1137 }
1138 else {
1139 ret = NULL;
1140 }
1141#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001142 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001143#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001144 if (ret == NULL)
1145 return(posix_error());
1146 return(PyString_FromString(ret));
1147}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001148#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001149
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001150#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001152"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154
1155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001156posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001157{
1158 char *ret;
1159 char buffer[L_ctermid];
1160
Greg Wardb48bc172000-03-01 21:51:56 +00001161#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001162 ret = ctermid_r(buffer);
1163#else
1164 ret = ctermid(buffer);
1165#endif
1166 if (ret == NULL)
1167 return(posix_error());
1168 return(PyString_FromString(buffer));
1169}
1170#endif
1171
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001172PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001173"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001179#ifdef MS_WINDOWS
1180 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1181#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1182 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001183#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001184 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1185 NULL, NULL);
1186#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001187 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001188#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189}
1190
Fred Drake4d1e64b2002-04-15 19:40:07 +00001191#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001193"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001194Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001196
1197static PyObject *
1198posix_fchdir(PyObject *self, PyObject *fdobj)
1199{
1200 return posix_fildes(fdobj, fchdir);
1201}
1202#endif /* HAVE_FCHDIR */
1203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001206"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001208
Barry Warsaw53699e91996-12-10 23:23:01 +00001209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001210posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211{
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001213 int i;
1214 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001215 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001216 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001217 return NULL;
1218 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001219 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001220 Py_END_ALLOW_THREADS
1221 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 return posix_error_with_allocated_filename(path);
1223 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001224 Py_INCREF(Py_None);
1225 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Martin v. Löwis244edc82001-10-04 22:44:26 +00001229#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001230PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001231"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001233
1234static PyObject *
1235posix_chroot(PyObject *self, PyObject *args)
1236{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001238}
1239#endif
1240
Guido van Rossum21142a01999-01-08 21:05:37 +00001241#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001242PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001243"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001245
1246static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001248{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001249 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001250}
1251#endif /* HAVE_FSYNC */
1252
1253#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001254
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001255#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001256extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1257#endif
1258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001260"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001261force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001262 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001263
1264static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001265posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001266{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001267 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001268}
1269#endif /* HAVE_FDATASYNC */
1270
1271
Fredrik Lundh10723342000-07-10 16:38:09 +00001272#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001273PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001274"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001276
Barry Warsaw53699e91996-12-10 23:23:01 +00001277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001279{
Mark Hammondef8b6542001-05-13 08:04:26 +00001280 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001281 int uid, gid;
1282 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001283 if (!PyArg_ParseTuple(args, "etii:chown",
1284 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001285 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001286 return NULL;
1287 Py_BEGIN_ALLOW_THREADS
1288 res = chown(path, (uid_t) uid, (gid_t) gid);
1289 Py_END_ALLOW_THREADS
1290 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001291 return posix_error_with_allocated_filename(path);
1292 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001293 Py_INCREF(Py_None);
1294 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001295}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001296#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001298#ifdef HAVE_LCHOWN
1299PyDoc_STRVAR(posix_lchown__doc__,
1300"lchown(path, uid, gid)\n\n\
1301Change the owner and group id of path to the numeric uid and gid.\n\
1302This function will not follow symbolic links.");
1303
1304static PyObject *
1305posix_lchown(PyObject *self, PyObject *args)
1306{
1307 char *path = NULL;
1308 int uid, gid;
1309 int res;
1310 if (!PyArg_ParseTuple(args, "etii:lchown",
1311 Py_FileSystemDefaultEncoding, &path,
1312 &uid, &gid))
1313 return NULL;
1314 Py_BEGIN_ALLOW_THREADS
1315 res = lchown(path, (uid_t) uid, (gid_t) gid);
1316 Py_END_ALLOW_THREADS
Neal Norwitze241ce82003-02-17 18:17:05 +00001317 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001318 return posix_error_with_allocated_filename(path);
1319 PyMem_Free(path);
1320 Py_INCREF(Py_None);
1321 return Py_None;
1322}
1323#endif /* HAVE_LCHOWN */
1324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001325
Guido van Rossum36bc6801995-06-14 22:54:23 +00001326#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001327PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001328"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001332posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333{
1334 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001335 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001336
Barry Warsaw53699e91996-12-10 23:23:01 +00001337 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001338#if defined(PYOS_OS2) && defined(PYCC_GCC)
1339 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001340#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001341 /* 0 = force Unix-style path if in the VMS DCL environment! */
1342 res = getcwd(buf, sizeof buf, 0);
1343#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001344 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001345#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001347 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351
Walter Dörwald3b918c32002-11-21 20:18:46 +00001352#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001353PyDoc_STRVAR(posix_getcwdu__doc__,
1354"getcwdu() -> path\n\n\
1355Return a unicode string representing the current working directory.");
1356
1357static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001358posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001359{
1360 char buf[1026];
1361 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001362
1363#ifdef Py_WIN_WIDE_FILENAMES
1364 if (unicode_file_names()) {
1365 wchar_t *wres;
1366 wchar_t wbuf[1026];
1367 Py_BEGIN_ALLOW_THREADS
1368 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1369 Py_END_ALLOW_THREADS
1370 if (wres == NULL)
1371 return posix_error();
1372 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1373 }
1374#endif
1375
1376 Py_BEGIN_ALLOW_THREADS
1377#if defined(PYOS_OS2) && defined(PYCC_GCC)
1378 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001379#elif defined(__VMS)
1380 /* 0 = force Unix-style path if in the VMS DCL environment! */
1381 res = getcwd(buf, sizeof buf, 0);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001382#else
1383 res = getcwd(buf, sizeof buf);
1384#endif
1385 Py_END_ALLOW_THREADS
1386 if (res == NULL)
1387 return posix_error();
1388 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1389}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001390#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001391#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001395PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001396"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001398
Barry Warsaw53699e91996-12-10 23:23:01 +00001399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001400posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001402 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001404#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001408"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001409Return a list containing the names of the entries in the directory.\n\
1410\n\
1411 path: path of directory to list\n\
1412\n\
1413The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001414entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001417posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001418{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001419 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001420 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001421#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001422
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001424 HANDLE hFindFile;
1425 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001426 /* MAX_PATH characters could mean a bigger encoded string */
1427 char namebuf[MAX_PATH*2+5];
1428 char *bufptr = namebuf;
1429 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001430
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431#ifdef Py_WIN_WIDE_FILENAMES
1432 /* If on wide-character-capable OS see if argument
1433 is Unicode and if so use wide API. */
1434 if (unicode_file_names()) {
1435 PyUnicodeObject *po;
1436 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1437 WIN32_FIND_DATAW wFileData;
1438 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1439 Py_UNICODE wch;
1440 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1441 wnamebuf[MAX_PATH] = L'\0';
1442 len = wcslen(wnamebuf);
1443 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1444 if (wch != L'/' && wch != L'\\' && wch != L':')
1445 wnamebuf[len++] = L'/';
1446 wcscpy(wnamebuf + len, L"*.*");
1447 if ((d = PyList_New(0)) == NULL)
1448 return NULL;
1449 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1450 if (hFindFile == INVALID_HANDLE_VALUE) {
1451 errno = GetLastError();
1452 if (errno == ERROR_FILE_NOT_FOUND) {
1453 return d;
1454 }
1455 Py_DECREF(d);
1456 return win32_error_unicode("FindFirstFileW", wnamebuf);
1457 }
1458 do {
1459 if (wFileData.cFileName[0] == L'.' &&
1460 (wFileData.cFileName[1] == L'\0' ||
1461 wFileData.cFileName[1] == L'.' &&
1462 wFileData.cFileName[2] == L'\0'))
1463 continue;
1464 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1465 if (v == NULL) {
1466 Py_DECREF(d);
1467 d = NULL;
1468 break;
1469 }
1470 if (PyList_Append(d, v) != 0) {
1471 Py_DECREF(v);
1472 Py_DECREF(d);
1473 d = NULL;
1474 break;
1475 }
1476 Py_DECREF(v);
1477 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1478
1479 if (FindClose(hFindFile) == FALSE) {
1480 Py_DECREF(d);
1481 return win32_error_unicode("FindClose", wnamebuf);
1482 }
1483 return d;
1484 }
1485 /* Drop the argument parsing error as narrow strings
1486 are also valid. */
1487 PyErr_Clear();
1488 }
1489#endif
1490
Tim Peters5aa91602002-01-30 05:46:57 +00001491 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001492 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001493 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001494 if (len > 0) {
1495 char ch = namebuf[len-1];
1496 if (ch != SEP && ch != ALTSEP && ch != ':')
1497 namebuf[len++] = '/';
1498 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001499 strcpy(namebuf + len, "*.*");
1500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001502 return NULL;
1503
1504 hFindFile = FindFirstFile(namebuf, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE) {
1506 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001507 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001508 return d;
1509 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001510 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001511 }
1512 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001513 if (FileData.cFileName[0] == '.' &&
1514 (FileData.cFileName[1] == '\0' ||
1515 FileData.cFileName[1] == '.' &&
1516 FileData.cFileName[2] == '\0'))
1517 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001518 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 d = NULL;
1522 break;
1523 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 if (PyList_Append(d, v) != 0) {
1525 Py_DECREF(v);
1526 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527 d = NULL;
1528 break;
1529 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001531 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1532
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001533 if (FindClose(hFindFile) == FALSE) {
1534 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001535 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001536 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537
1538 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001539
Tim Peters0bb44a42000-09-15 07:44:49 +00001540#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001541
1542#ifndef MAX_PATH
1543#define MAX_PATH CCHMAXPATH
1544#endif
1545 char *name, *pt;
1546 int len;
1547 PyObject *d, *v;
1548 char namebuf[MAX_PATH+5];
1549 HDIR hdir = 1;
1550 ULONG srchcnt = 1;
1551 FILEFINDBUF3 ep;
1552 APIRET rc;
1553
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001554 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001555 return NULL;
1556 if (len >= MAX_PATH) {
1557 PyErr_SetString(PyExc_ValueError, "path too long");
1558 return NULL;
1559 }
1560 strcpy(namebuf, name);
1561 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001562 if (*pt == ALTSEP)
1563 *pt = SEP;
1564 if (namebuf[len-1] != SEP)
1565 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001566 strcpy(namebuf + len, "*.*");
1567
1568 if ((d = PyList_New(0)) == NULL)
1569 return NULL;
1570
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001571 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1572 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001573 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001574 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1575 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1576 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001577
1578 if (rc != NO_ERROR) {
1579 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001580 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001581 }
1582
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001583 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001584 do {
1585 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001586 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001587 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001588
1589 strcpy(namebuf, ep.achName);
1590
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001591 /* Leave Case of Name Alone -- In Native Form */
1592 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001593
1594 v = PyString_FromString(namebuf);
1595 if (v == NULL) {
1596 Py_DECREF(d);
1597 d = NULL;
1598 break;
1599 }
1600 if (PyList_Append(d, v) != 0) {
1601 Py_DECREF(v);
1602 Py_DECREF(d);
1603 d = NULL;
1604 break;
1605 }
1606 Py_DECREF(v);
1607 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1608 }
1609
1610 return d;
1611#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001612
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001613 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001615 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001616 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001617 int arg_is_unicode = 1;
1618
1619 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1620 arg_is_unicode = 0;
1621 PyErr_Clear();
1622 }
1623 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001624 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001625 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001626 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001627 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001628 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001630 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631 return NULL;
1632 }
1633 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001634 if (ep->d_name[0] == '.' &&
1635 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001636 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001637 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001638 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001639 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 d = NULL;
1642 break;
1643 }
Just van Rossum46c97842003-02-25 21:42:15 +00001644#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001645 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001646 PyObject *w;
1647
1648 w = PyUnicode_FromEncodedObject(v,
1649 Py_FileSystemDefaultEncoding,
1650 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001651 if (w != NULL) {
1652 Py_DECREF(v);
1653 v = w;
1654 }
1655 else {
1656 /* fall back to the original byte string, as
1657 discussed in patch #683592 */
1658 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001659 }
Just van Rossum46c97842003-02-25 21:42:15 +00001660 }
1661#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 if (PyList_Append(d, v) != 0) {
1663 Py_DECREF(v);
1664 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665 d = NULL;
1666 break;
1667 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001668 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669 }
1670 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001671 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001672
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001674
Tim Peters0bb44a42000-09-15 07:44:49 +00001675#endif /* which OS */
1676} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001677
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001678#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001679/* A helper function for abspath on win32 */
1680static PyObject *
1681posix__getfullpathname(PyObject *self, PyObject *args)
1682{
1683 /* assume encoded strings wont more than double no of chars */
1684 char inbuf[MAX_PATH*2];
1685 char *inbufp = inbuf;
1686 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1687 char outbuf[MAX_PATH*2];
1688 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001689#ifdef Py_WIN_WIDE_FILENAMES
1690 if (unicode_file_names()) {
1691 PyUnicodeObject *po;
1692 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1693 Py_UNICODE woutbuf[MAX_PATH*2];
1694 Py_UNICODE *wtemp;
1695 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1696 sizeof(woutbuf)/sizeof(woutbuf[0]),
1697 woutbuf, &wtemp))
1698 return win32_error("GetFullPathName", "");
1699 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1700 }
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1704 }
1705#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001706 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1707 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 &insize))
1709 return NULL;
1710 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1711 outbuf, &temp))
1712 return win32_error("GetFullPathName", inbuf);
1713 return PyString_FromString(outbuf);
1714} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001715#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001717PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001718"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001720
Barry Warsaw53699e91996-12-10 23:23:01 +00001721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001722posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001724 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001725 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001726 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727
1728#ifdef Py_WIN_WIDE_FILENAMES
1729 if (unicode_file_names()) {
1730 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001731 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001732 Py_BEGIN_ALLOW_THREADS
1733 /* PyUnicode_AS_UNICODE OK without thread lock as
1734 it is a simple dereference. */
1735 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1736 Py_END_ALLOW_THREADS
1737 if (res < 0)
1738 return posix_error();
1739 Py_INCREF(Py_None);
1740 return Py_None;
1741 }
1742 /* Drop the argument parsing error as narrow strings
1743 are also valid. */
1744 PyErr_Clear();
1745 }
1746#endif
1747
Tim Peters5aa91602002-01-30 05:46:57 +00001748 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001749 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001751 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001752#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001753 res = mkdir(path);
1754#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001755 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001756#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001757 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001758 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001759 return posix_error_with_allocated_filename(path);
1760 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001761 Py_INCREF(Py_None);
1762 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763}
1764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001765
Guido van Rossumb6775db1994-08-01 11:34:53 +00001766#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001767#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1768#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1769#include <sys/resource.h>
1770#endif
1771#endif
1772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"nice(inc) -> new_priority\n\n\
1775Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001779{
1780 int increment, value;
1781
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001783 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001784
1785 /* There are two flavours of 'nice': one that returns the new
1786 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001787 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1788 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001789
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001790 If we are of the nice family that returns the new priority, we
1791 need to clear errno before the call, and check if errno is filled
1792 before calling posix_error() on a returnvalue of -1, because the
1793 -1 may be the actual new priority! */
1794
1795 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001796 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001797#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001798 if (value == 0)
1799 value = getpriority(PRIO_PROCESS, 0);
1800#endif
1801 if (value == -1 && errno != 0)
1802 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001804 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001808
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001810"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001812
Barry Warsaw53699e91996-12-10 23:23:01 +00001813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001814posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001815{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001816#ifdef MS_WINDOWS
1817 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1818#else
1819 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1820#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001821}
1822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001824PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001825"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001827
Barry Warsaw53699e91996-12-10 23:23:01 +00001828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001829posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001831#ifdef MS_WINDOWS
1832 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1833#else
1834 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1835#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836}
1837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001840"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Barry Warsaw53699e91996-12-10 23:23:01 +00001843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001844posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001846#ifdef MS_WINDOWS
1847 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1848#else
1849 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1850#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001851}
1852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001854#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001855PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001856"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001861{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001862 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001863 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001864 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001867 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_END_ALLOW_THREADS
1869 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001870}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001871#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001874PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001875"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001879posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001880{
1881 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001882 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001883 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001884 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 if (i < 0)
1886 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001887 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001888}
1889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001891PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001892"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001893Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001896"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001901{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001902#ifdef MS_WINDOWS
1903 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1904#else
1905 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1906#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907}
1908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Guido van Rossumb6775db1994-08-01 11:34:53 +00001910#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001912"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914
Barry Warsaw53699e91996-12-10 23:23:01 +00001915static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001916posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001917{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001918 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001919 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001920
Barry Warsaw53699e91996-12-10 23:23:01 +00001921 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001922 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001924 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001925 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001926 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001927 u.sysname,
1928 u.nodename,
1929 u.release,
1930 u.version,
1931 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001932}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001933#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001934
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001935static int
1936extract_time(PyObject *t, long* sec, long* usec)
1937{
1938 long intval;
1939 if (PyFloat_Check(t)) {
1940 double tval = PyFloat_AsDouble(t);
1941 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1942 if (!intobj)
1943 return -1;
1944 intval = PyInt_AsLong(intobj);
1945 Py_DECREF(intobj);
1946 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001947 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001948 if (*usec < 0)
1949 /* If rounding gave us a negative number,
1950 truncate. */
1951 *usec = 0;
1952 return 0;
1953 }
1954 intval = PyInt_AsLong(t);
1955 if (intval == -1 && PyErr_Occurred())
1956 return -1;
1957 *sec = intval;
1958 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001959 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001960}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001963"utime(path, (atime, utime))\n\
1964utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001965Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Barry Warsaw53699e91996-12-10 23:23:01 +00001968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001969posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001970{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001971 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001972 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001973 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001974 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001975
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001976#if defined(HAVE_UTIMES)
1977 struct timeval buf[2];
1978#define ATIME buf[0].tv_sec
1979#define MTIME buf[1].tv_sec
1980#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001981/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001982 struct utimbuf buf;
1983#define ATIME buf.actime
1984#define MTIME buf.modtime
1985#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001986#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001987 time_t buf[2];
1988#define ATIME buf[0]
1989#define MTIME buf[1]
1990#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001991#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001992
Barry Warsaw3cef8562000-05-01 16:17:24 +00001993 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001994 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001995 if (arg == Py_None) {
1996 /* optional time values not given */
1997 Py_BEGIN_ALLOW_THREADS
1998 res = utime(path, NULL);
1999 Py_END_ALLOW_THREADS
2000 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002001 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002002 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002003 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002004 return NULL;
2005 }
2006 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002007 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2008 &atime, &ausec) == -1)
2009 return NULL;
2010 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2011 &mtime, &musec) == -1)
2012 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002013 ATIME = atime;
2014 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002015#ifdef HAVE_UTIMES
2016 buf[0].tv_usec = ausec;
2017 buf[1].tv_usec = musec;
2018 Py_BEGIN_ALLOW_THREADS
2019 res = utimes(path, buf);
2020 Py_END_ALLOW_THREADS
2021#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002022 Py_BEGIN_ALLOW_THREADS
2023 res = utime(path, UTIME_ARG);
2024 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002025#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002026 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002027 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002028 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002029 Py_INCREF(Py_None);
2030 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002031#undef UTIME_ARG
2032#undef ATIME
2033#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034}
2035
Guido van Rossum85e3b011991-06-03 12:42:10 +00002036
Guido van Rossum3b066191991-06-04 19:40:25 +00002037/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002038
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042
Barry Warsaw53699e91996-12-10 23:23:01 +00002043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002044posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002045{
2046 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002047 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002048 return NULL;
2049 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002050 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051}
2052
Martin v. Löwis114619e2002-10-07 06:44:21 +00002053#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2054static void
2055free_string_array(char **array, int count)
2056{
2057 int i;
2058 for (i = 0; i < count; i++)
2059 PyMem_Free(array[i]);
2060 PyMem_DEL(array);
2061}
2062#endif
2063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002065#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002067"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068Execute an executable path with arguments, replacing current process.\n\
2069\n\
2070 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002075{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002076 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002078 char **argvlist;
2079 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002081
Guido van Rossum89b33251993-10-22 14:26:06 +00002082 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083 argv is a list or tuple of strings. */
2084
Martin v. Löwis114619e2002-10-07 06:44:21 +00002085 if (!PyArg_ParseTuple(args, "etO:execv",
2086 Py_FileSystemDefaultEncoding,
2087 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002088 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002089 if (PyList_Check(argv)) {
2090 argc = PyList_Size(argv);
2091 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002092 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002093 else if (PyTuple_Check(argv)) {
2094 argc = PyTuple_Size(argv);
2095 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002096 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002097 else {
Fred Drake661ea262000-10-24 19:57:45 +00002098 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002099 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002100 return NULL;
2101 }
2102
2103 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002104 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002105 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002106 return NULL;
2107 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002108
Barry Warsaw53699e91996-12-10 23:23:01 +00002109 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002110 if (argvlist == NULL) {
2111 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002112 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002113 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002115 if (!PyArg_Parse((*getitem)(argv, i), "et",
2116 Py_FileSystemDefaultEncoding,
2117 &argvlist[i])) {
2118 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002119 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002120 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002121 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002123
Guido van Rossum85e3b011991-06-03 12:42:10 +00002124 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125 }
2126 argvlist[argc] = NULL;
2127
Guido van Rossumb6775db1994-08-01 11:34:53 +00002128#ifdef BAD_EXEC_PROTOTYPES
2129 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002130#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002131 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133
Guido van Rossum85e3b011991-06-03 12:42:10 +00002134 /* If we get here it's definitely an error */
2135
Martin v. Löwis114619e2002-10-07 06:44:21 +00002136 free_string_array(argvlist, argc);
2137 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002138 return posix_error();
2139}
2140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002144Execute a path with arguments and environment, replacing current process.\n\
2145\n\
2146 path: path of executable file\n\
2147 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002148 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002149
Barry Warsaw53699e91996-12-10 23:23:01 +00002150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002151posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002152{
2153 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002154 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002155 char **argvlist;
2156 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002157 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002158 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002160 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002161
2162 /* execve has three arguments: (path, argv, env), where
2163 argv is a list or tuple of strings and env is a dictionary
2164 like posix.environ. */
2165
Martin v. Löwis114619e2002-10-07 06:44:21 +00002166 if (!PyArg_ParseTuple(args, "etOO:execve",
2167 Py_FileSystemDefaultEncoding,
2168 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002170 if (PyList_Check(argv)) {
2171 argc = PyList_Size(argv);
2172 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002174 else if (PyTuple_Check(argv)) {
2175 argc = PyTuple_Size(argv);
2176 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002177 }
2178 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002179 PyErr_SetString(PyExc_TypeError,
2180 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002181 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002182 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002183 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002184 PyErr_SetString(PyExc_TypeError,
2185 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002186 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002187 }
2188
Guido van Rossum50422b42000-04-26 20:34:28 +00002189 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002190 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002191 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002192 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002193 }
2194
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002196 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002199 }
2200 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002202 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002203 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002204 &argvlist[i]))
2205 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002206 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002207 goto fail_1;
2208 }
2209 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002210 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002211 argvlist[argc] = NULL;
2212
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002213 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002214 if (i < 0)
2215 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002216 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002217 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002218 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002219 goto fail_1;
2220 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002221 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002222 keys = PyMapping_Keys(env);
2223 vals = PyMapping_Values(env);
2224 if (!keys || !vals)
2225 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002226 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2227 PyErr_SetString(PyExc_TypeError,
2228 "execve(): env.keys() or env.values() is not a list");
2229 goto fail_2;
2230 }
Tim Peters5aa91602002-01-30 05:46:57 +00002231
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002232 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002233 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002234 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002235
2236 key = PyList_GetItem(keys, pos);
2237 val = PyList_GetItem(vals, pos);
2238 if (!key || !val)
2239 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002240
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002241 if (!PyArg_Parse(
2242 key,
2243 "s;execve() arg 3 contains a non-string key",
2244 &k) ||
2245 !PyArg_Parse(
2246 val,
2247 "s;execve() arg 3 contains a non-string value",
2248 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002249 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002250 goto fail_2;
2251 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002252
2253#if defined(PYOS_OS2)
2254 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2255 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2256#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002257 len = PyString_Size(key) + PyString_Size(val) + 2;
2258 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002259 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 goto fail_2;
2262 }
Tim Petersc8996f52001-12-03 20:41:00 +00002263 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002264 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002265#if defined(PYOS_OS2)
2266 }
2267#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002268 }
2269 envlist[envc] = 0;
2270
Guido van Rossumb6775db1994-08-01 11:34:53 +00002271
2272#ifdef BAD_EXEC_PROTOTYPES
2273 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002274#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002275 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002276#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002277
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002278 /* If we get here it's definitely an error */
2279
2280 (void) posix_error();
2281
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002282 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002283 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002284 PyMem_DEL(envlist[envc]);
2285 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002286 fail_1:
2287 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002288 Py_XDECREF(vals);
2289 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002290 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002291 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002292 return NULL;
2293}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002294#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Guido van Rossuma1065681999-01-25 23:20:23 +00002297#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002299"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002300Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002301\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002302 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002303 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002305
2306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002307posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002308{
2309 char *path;
2310 PyObject *argv;
2311 char **argvlist;
2312 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002313 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002314 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002315
2316 /* spawnv has three arguments: (mode, path, argv), where
2317 argv is a list or tuple of strings. */
2318
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2320 Py_FileSystemDefaultEncoding,
2321 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002322 return NULL;
2323 if (PyList_Check(argv)) {
2324 argc = PyList_Size(argv);
2325 getitem = PyList_GetItem;
2326 }
2327 else if (PyTuple_Check(argv)) {
2328 argc = PyTuple_Size(argv);
2329 getitem = PyTuple_GetItem;
2330 }
2331 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002332 PyErr_SetString(PyExc_TypeError,
2333 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002335 return NULL;
2336 }
2337
2338 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002339 if (argvlist == NULL) {
2340 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002341 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002342 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002343 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 if (!PyArg_Parse((*getitem)(argv, i), "et",
2345 Py_FileSystemDefaultEncoding,
2346 &argvlist[i])) {
2347 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002348 PyErr_SetString(
2349 PyExc_TypeError,
2350 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002352 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002353 }
2354 }
2355 argvlist[argc] = NULL;
2356
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002357#if defined(PYOS_OS2) && defined(PYCC_GCC)
2358 Py_BEGIN_ALLOW_THREADS
2359 spawnval = spawnv(mode, path, argvlist);
2360 Py_END_ALLOW_THREADS
2361#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002362 if (mode == _OLD_P_OVERLAY)
2363 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002364
Tim Peters25059d32001-12-07 20:35:43 +00002365 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002366 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002367 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002368#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002369
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 free_string_array(argvlist, argc);
2371 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002372
Fred Drake699f3522000-06-29 21:12:41 +00002373 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002374 return posix_error();
2375 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002376#if SIZEOF_LONG == SIZEOF_VOID_P
2377 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002378#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002379 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002380#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002381}
2382
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002386Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002387\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002388 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002389 path: path of executable file\n\
2390 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002392
2393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002394posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002395{
2396 char *path;
2397 PyObject *argv, *env;
2398 char **argvlist;
2399 char **envlist;
2400 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2401 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002402 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002403 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002404 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002405
2406 /* spawnve has four arguments: (mode, path, argv, env), where
2407 argv is a list or tuple of strings and env is a dictionary
2408 like posix.environ. */
2409
Martin v. Löwis114619e2002-10-07 06:44:21 +00002410 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2411 Py_FileSystemDefaultEncoding,
2412 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 return NULL;
2414 if (PyList_Check(argv)) {
2415 argc = PyList_Size(argv);
2416 getitem = PyList_GetItem;
2417 }
2418 else if (PyTuple_Check(argv)) {
2419 argc = PyTuple_Size(argv);
2420 getitem = PyTuple_GetItem;
2421 }
2422 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002423 PyErr_SetString(PyExc_TypeError,
2424 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002425 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002426 }
2427 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002428 PyErr_SetString(PyExc_TypeError,
2429 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002430 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002431 }
2432
2433 argvlist = PyMem_NEW(char *, argc+1);
2434 if (argvlist == NULL) {
2435 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002436 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002437 }
2438 for (i = 0; i < argc; i++) {
2439 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002440 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002441 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002442 &argvlist[i]))
2443 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002444 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002445 goto fail_1;
2446 }
2447 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002448 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002449 argvlist[argc] = NULL;
2450
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002451 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002452 if (i < 0)
2453 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002454 envlist = PyMem_NEW(char *, i + 1);
2455 if (envlist == NULL) {
2456 PyErr_NoMemory();
2457 goto fail_1;
2458 }
2459 envc = 0;
2460 keys = PyMapping_Keys(env);
2461 vals = PyMapping_Values(env);
2462 if (!keys || !vals)
2463 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002464 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2465 PyErr_SetString(PyExc_TypeError,
2466 "spawnve(): env.keys() or env.values() is not a list");
2467 goto fail_2;
2468 }
Tim Peters5aa91602002-01-30 05:46:57 +00002469
Guido van Rossuma1065681999-01-25 23:20:23 +00002470 for (pos = 0; pos < i; pos++) {
2471 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002472 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002473
2474 key = PyList_GetItem(keys, pos);
2475 val = PyList_GetItem(vals, pos);
2476 if (!key || !val)
2477 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002478
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002479 if (!PyArg_Parse(
2480 key,
2481 "s;spawnve() arg 3 contains a non-string key",
2482 &k) ||
2483 !PyArg_Parse(
2484 val,
2485 "s;spawnve() arg 3 contains a non-string value",
2486 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002487 {
2488 goto fail_2;
2489 }
Tim Petersc8996f52001-12-03 20:41:00 +00002490 len = PyString_Size(key) + PyString_Size(val) + 2;
2491 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002492 if (p == NULL) {
2493 PyErr_NoMemory();
2494 goto fail_2;
2495 }
Tim Petersc8996f52001-12-03 20:41:00 +00002496 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002497 envlist[envc++] = p;
2498 }
2499 envlist[envc] = 0;
2500
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002501#if defined(PYOS_OS2) && defined(PYCC_GCC)
2502 Py_BEGIN_ALLOW_THREADS
2503 spawnval = spawnve(mode, path, argvlist, envlist);
2504 Py_END_ALLOW_THREADS
2505#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002506 if (mode == _OLD_P_OVERLAY)
2507 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002508
2509 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002510 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002511 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002512#endif
Tim Peters25059d32001-12-07 20:35:43 +00002513
Fred Drake699f3522000-06-29 21:12:41 +00002514 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002515 (void) posix_error();
2516 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002517#if SIZEOF_LONG == SIZEOF_VOID_P
2518 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002519#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002520 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002522
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002523 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002524 while (--envc >= 0)
2525 PyMem_DEL(envlist[envc]);
2526 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002527 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002528 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002529 Py_XDECREF(vals);
2530 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002531 fail_0:
2532 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002533 return res;
2534}
2535#endif /* HAVE_SPAWNV */
2536
2537
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002538#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002540"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002541Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2542\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002544
2545static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002546posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002547{
Neal Norwitze241ce82003-02-17 18:17:05 +00002548 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002549 if (pid == -1)
2550 return posix_error();
2551 PyOS_AfterFork();
2552 return PyInt_FromLong((long)pid);
2553}
2554#endif
2555
2556
Guido van Rossumad0ee831995-03-01 10:34:45 +00002557#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002559"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002560Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002561Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002562
Barry Warsaw53699e91996-12-10 23:23:01 +00002563static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002564posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002565{
Neal Norwitze241ce82003-02-17 18:17:05 +00002566 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002567 if (pid == -1)
2568 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002569 if (pid == 0)
2570 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002571 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002572}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002573#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002574
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.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004357 */
Tim Peters736aa322000-09-01 06:51:24 +00004358
4359 /* RED_FLAG 31-Aug-2000 Tim
4360 * This is always called (today!) between a pair of
4361 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4362 * macros. So the thread running this has no valid thread state, as
4363 * far as Python is concerned. However, this calls some Python API
4364 * functions that cannot be called safely without a valid thread
4365 * state, in particular PyDict_GetItem.
4366 * As a temporary hack (although it may last for years ...), we
4367 * *rely* on not having a valid thread state in this function, in
4368 * order to create our own "from scratch".
4369 * This will deadlock if _PyPclose is ever called by a thread
4370 * holding the global lock.
4371 */
4372
Fredrik Lundh56055a42000-07-23 19:47:12 +00004373static int _PyPclose(FILE *file)
4374{
Fredrik Lundh20318932000-07-26 17:29:12 +00004375 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004376 DWORD exit_code;
4377 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004378 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4379 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004380#ifdef WITH_THREAD
4381 PyInterpreterState* pInterpreterState;
4382 PyThreadState* pThreadState;
4383#endif
4384
Fredrik Lundh20318932000-07-26 17:29:12 +00004385 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004386 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004387 */
4388 result = fclose(file);
4389
Tim Peters736aa322000-09-01 06:51:24 +00004390#ifdef WITH_THREAD
4391 /* Bootstrap a valid thread state into existence. */
4392 pInterpreterState = PyInterpreterState_New();
4393 if (!pInterpreterState) {
4394 /* Well, we're hosed now! We don't have a thread
4395 * state, so can't call a nice error routine, or raise
4396 * an exception. Just die.
4397 */
4398 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004399 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004400 return -1; /* unreachable */
4401 }
4402 pThreadState = PyThreadState_New(pInterpreterState);
4403 if (!pThreadState) {
4404 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004405 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004406 return -1; /* unreachable */
4407 }
4408 /* Grab the global lock. Note that this will deadlock if the
4409 * current thread already has the lock! (see RED_FLAG comments
4410 * before this function)
4411 */
4412 PyEval_RestoreThread(pThreadState);
4413#endif
4414
Fredrik Lundh56055a42000-07-23 19:47:12 +00004415 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004416 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4417 (procObj = PyDict_GetItem(_PyPopenProcs,
4418 fileObj)) != NULL &&
4419 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4420 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4421
4422 hProcess = PyLong_AsVoidPtr(hProcessObj);
4423 file_count = PyInt_AsLong(intObj);
4424
4425 if (file_count > 1) {
4426 /* Still other files referencing process */
4427 file_count--;
4428 PyList_SetItem(procObj,1,
4429 PyInt_FromLong(file_count));
4430 } else {
4431 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004432 if (result != EOF &&
4433 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4434 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004435 /* Possible truncation here in 16-bit environments, but
4436 * real exit codes are just the lower byte in any event.
4437 */
4438 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004439 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004440 /* Indicate failure - this will cause the file object
4441 * to raise an I/O error and translate the last Win32
4442 * error code from errno. We do have a problem with
4443 * last errors that overlap the normal errno table,
4444 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004445 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004446 if (result != EOF) {
4447 /* If the error wasn't from the fclose(), then
4448 * set errno for the file object error handling.
4449 */
4450 errno = GetLastError();
4451 }
4452 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004453 }
4454
4455 /* Free up the native handle at this point */
4456 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004457 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004458
Mark Hammondb37a3732000-08-14 04:47:33 +00004459 /* Remove this file pointer from dictionary */
4460 PyDict_DelItem(_PyPopenProcs, fileObj);
4461
4462 if (PyDict_Size(_PyPopenProcs) == 0) {
4463 Py_DECREF(_PyPopenProcs);
4464 _PyPopenProcs = NULL;
4465 }
4466
4467 } /* if object retrieval ok */
4468
4469 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004470 } /* if _PyPopenProcs */
4471
Tim Peters736aa322000-09-01 06:51:24 +00004472#ifdef WITH_THREAD
4473 /* Tear down the thread & interpreter states.
4474 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004475 * call the thread clear & delete functions, and indeed insist on
4476 * doing that themselves. The lock must be held during the clear, but
4477 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004478 */
4479 PyInterpreterState_Clear(pInterpreterState);
4480 PyEval_ReleaseThread(pThreadState);
4481 PyInterpreterState_Delete(pInterpreterState);
4482#endif
4483
Fredrik Lundh56055a42000-07-23 19:47:12 +00004484 return result;
4485}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004486
4487#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004489posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004490{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004491 char *name;
4492 char *mode = "r";
4493 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004494 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004495 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004496 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004497 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004498 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004499 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004501 if (fp == NULL)
4502 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004503 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004504 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004505 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004506 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004507}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004508
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004509#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004510#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Guido van Rossumb6775db1994-08-01 11:34:53 +00004513#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004514PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004515"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004516Set the current process's user id.");
4517
Barry Warsaw53699e91996-12-10 23:23:01 +00004518static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004519posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004520{
4521 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004522 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004523 return NULL;
4524 if (setuid(uid) < 0)
4525 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004526 Py_INCREF(Py_None);
4527 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004528}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004529#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004531
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004532#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004533PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004534"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004535Set the current process's effective user id.");
4536
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004537static PyObject *
4538posix_seteuid (PyObject *self, PyObject *args)
4539{
4540 int euid;
4541 if (!PyArg_ParseTuple(args, "i", &euid)) {
4542 return NULL;
4543 } else if (seteuid(euid) < 0) {
4544 return posix_error();
4545 } else {
4546 Py_INCREF(Py_None);
4547 return Py_None;
4548 }
4549}
4550#endif /* HAVE_SETEUID */
4551
4552#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004553PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004554"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004555Set the current process's effective group id.");
4556
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004557static PyObject *
4558posix_setegid (PyObject *self, PyObject *args)
4559{
4560 int egid;
4561 if (!PyArg_ParseTuple(args, "i", &egid)) {
4562 return NULL;
4563 } else if (setegid(egid) < 0) {
4564 return posix_error();
4565 } else {
4566 Py_INCREF(Py_None);
4567 return Py_None;
4568 }
4569}
4570#endif /* HAVE_SETEGID */
4571
4572#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004573PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004574"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004575Set the current process's real and effective user ids.");
4576
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004577static PyObject *
4578posix_setreuid (PyObject *self, PyObject *args)
4579{
4580 int ruid, euid;
4581 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4582 return NULL;
4583 } else if (setreuid(ruid, euid) < 0) {
4584 return posix_error();
4585 } else {
4586 Py_INCREF(Py_None);
4587 return Py_None;
4588 }
4589}
4590#endif /* HAVE_SETREUID */
4591
4592#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004593PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004594"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004595Set the current process's real and effective group ids.");
4596
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004597static PyObject *
4598posix_setregid (PyObject *self, PyObject *args)
4599{
4600 int rgid, egid;
4601 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4602 return NULL;
4603 } else if (setregid(rgid, egid) < 0) {
4604 return posix_error();
4605 } else {
4606 Py_INCREF(Py_None);
4607 return Py_None;
4608 }
4609}
4610#endif /* HAVE_SETREGID */
4611
Guido van Rossumb6775db1994-08-01 11:34:53 +00004612#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004613PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004614"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004615Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004616
Barry Warsaw53699e91996-12-10 23:23:01 +00004617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004618posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004619{
4620 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004621 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004622 return NULL;
4623 if (setgid(gid) < 0)
4624 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004625 Py_INCREF(Py_None);
4626 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004627}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004628#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004629
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004630#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004631PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004632"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004634
4635static PyObject *
4636posix_setgroups(PyObject *self, PyObject *args)
4637{
4638 PyObject *groups;
4639 int i, len;
4640 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004641
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004642 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4643 return NULL;
4644 if (!PySequence_Check(groups)) {
4645 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4646 return NULL;
4647 }
4648 len = PySequence_Size(groups);
4649 if (len > MAX_GROUPS) {
4650 PyErr_SetString(PyExc_ValueError, "too many groups");
4651 return NULL;
4652 }
4653 for(i = 0; i < len; i++) {
4654 PyObject *elem;
4655 elem = PySequence_GetItem(groups, i);
4656 if (!elem)
4657 return NULL;
4658 if (!PyInt_Check(elem)) {
4659 PyErr_SetString(PyExc_TypeError,
4660 "groups must be integers");
4661 Py_DECREF(elem);
4662 return NULL;
4663 }
4664 /* XXX: check that value fits into gid_t. */
4665 grouplist[i] = PyInt_AsLong(elem);
4666 Py_DECREF(elem);
4667 }
4668
4669 if (setgroups(len, grouplist) < 0)
4670 return posix_error();
4671 Py_INCREF(Py_None);
4672 return Py_None;
4673}
4674#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004675
Guido van Rossumb6775db1994-08-01 11:34:53 +00004676#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004677PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004678"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004679Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004680
Barry Warsaw53699e91996-12-10 23:23:01 +00004681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004682posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004683{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004684 int pid, options;
4685#ifdef UNION_WAIT
4686 union wait status;
4687#define status_i (status.w_status)
4688#else
4689 int status;
4690#define status_i status
4691#endif
4692 status_i = 0;
4693
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004694 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004695 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004696 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004697 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004698 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004699 if (pid == -1)
4700 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004701 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004702 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004703}
4704
Tim Petersab034fa2002-02-01 11:27:43 +00004705#elif defined(HAVE_CWAIT)
4706
4707/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004708PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004709"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004710"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004711
4712static PyObject *
4713posix_waitpid(PyObject *self, PyObject *args)
4714{
4715 int pid, options;
4716 int status;
4717
4718 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4719 return NULL;
4720 Py_BEGIN_ALLOW_THREADS
4721 pid = _cwait(&status, pid, options);
4722 Py_END_ALLOW_THREADS
4723 if (pid == -1)
4724 return posix_error();
4725 else
4726 /* shift the status left a byte so this is more like the
4727 POSIX waitpid */
4728 return Py_BuildValue("ii", pid, status << 8);
4729}
4730#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004731
Guido van Rossumad0ee831995-03-01 10:34:45 +00004732#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004733PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004734"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004735Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004736
Barry Warsaw53699e91996-12-10 23:23:01 +00004737static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004738posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004739{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004740 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004741#ifdef UNION_WAIT
4742 union wait status;
4743#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004744#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004745 int status;
4746#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004747#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004748
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004749 status_i = 0;
4750 Py_BEGIN_ALLOW_THREADS
4751 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004752 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004753 if (pid == -1)
4754 return posix_error();
4755 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004756 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004757#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004758}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004759#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004761
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004762PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004763"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004764Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004765
Barry Warsaw53699e91996-12-10 23:23:01 +00004766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004767posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004768{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004769#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004770 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004771#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004772#ifdef MS_WINDOWS
4773 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4774#else
4775 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4776#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004777#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004778}
4779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004780
Guido van Rossumb6775db1994-08-01 11:34:53 +00004781#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004782PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004783"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004784Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004785
Barry Warsaw53699e91996-12-10 23:23:01 +00004786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004787posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004788{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004789 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004790 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004791 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004792 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004793 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004794 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004795 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004796 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004797 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004798 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004799 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004800}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004801#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004802
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004803
Guido van Rossumb6775db1994-08-01 11:34:53 +00004804#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004805PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004806"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004808
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004810posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004811{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004812 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004813}
4814#endif /* HAVE_SYMLINK */
4815
4816
4817#ifdef HAVE_TIMES
4818#ifndef HZ
4819#define HZ 60 /* Universal constant :-) */
4820#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004821
Guido van Rossumd48f2521997-12-05 22:19:34 +00004822#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4823static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004824system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004825{
4826 ULONG value = 0;
4827
4828 Py_BEGIN_ALLOW_THREADS
4829 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4830 Py_END_ALLOW_THREADS
4831
4832 return value;
4833}
4834
4835static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004836posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004837{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004838 /* Currently Only Uptime is Provided -- Others Later */
4839 return Py_BuildValue("ddddd",
4840 (double)0 /* t.tms_utime / HZ */,
4841 (double)0 /* t.tms_stime / HZ */,
4842 (double)0 /* t.tms_cutime / HZ */,
4843 (double)0 /* t.tms_cstime / HZ */,
4844 (double)system_uptime() / 1000);
4845}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004846#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004847static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004848posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004849{
4850 struct tms t;
4851 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004852 errno = 0;
4853 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004854 if (c == (clock_t) -1)
4855 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004856 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004857 (double)t.tms_utime / HZ,
4858 (double)t.tms_stime / HZ,
4859 (double)t.tms_cutime / HZ,
4860 (double)t.tms_cstime / HZ,
4861 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004862}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004863#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004864#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004865
4866
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004867#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004868#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004869static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004870posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004871{
4872 FILETIME create, exit, kernel, user;
4873 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004874 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004875 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4876 /* The fields of a FILETIME structure are the hi and lo part
4877 of a 64-bit value expressed in 100 nanosecond units.
4878 1e7 is one second in such units; 1e-7 the inverse.
4879 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4880 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 return Py_BuildValue(
4882 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004883 (double)(kernel.dwHighDateTime*429.4967296 +
4884 kernel.dwLowDateTime*1e-7),
4885 (double)(user.dwHighDateTime*429.4967296 +
4886 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004887 (double)0,
4888 (double)0,
4889 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004890}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004891#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004892
4893#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004895"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004896Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004897#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004899
Guido van Rossumb6775db1994-08-01 11:34:53 +00004900#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004901PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004902"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004903Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004904
Barry Warsaw53699e91996-12-10 23:23:01 +00004905static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004906posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004907{
Guido van Rossum687dd131993-05-17 08:34:16 +00004908 if (setsid() < 0)
4909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 Py_INCREF(Py_None);
4911 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004912}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004913#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004914
Guido van Rossumb6775db1994-08-01 11:34:53 +00004915#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004917"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004918Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004919
Barry Warsaw53699e91996-12-10 23:23:01 +00004920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004921posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004922{
4923 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004924 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004925 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004926 if (setpgid(pid, pgrp) < 0)
4927 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004928 Py_INCREF(Py_None);
4929 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004930}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004931#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004933
Guido van Rossumb6775db1994-08-01 11:34:53 +00004934#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004935PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004936"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004937Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004938
Barry Warsaw53699e91996-12-10 23:23:01 +00004939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004940posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004941{
4942 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004943 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004944 return NULL;
4945 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004946 if (pgid < 0)
4947 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004948 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004949}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004950#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004952
Guido van Rossumb6775db1994-08-01 11:34:53 +00004953#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004954PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004955"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004957
Barry Warsaw53699e91996-12-10 23:23:01 +00004958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004959posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004960{
4961 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004962 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004963 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004964 if (tcsetpgrp(fd, pgid) < 0)
4965 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004966 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004967 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004968}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004969#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004970
Guido van Rossum687dd131993-05-17 08:34:16 +00004971/* Functions acting on file descriptors */
4972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004973PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004974"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004976
Barry Warsaw53699e91996-12-10 23:23:01 +00004977static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004978posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004979{
Mark Hammondef8b6542001-05-13 08:04:26 +00004980 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004981 int flag;
4982 int mode = 0777;
4983 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004984
4985#ifdef MS_WINDOWS
4986 if (unicode_file_names()) {
4987 PyUnicodeObject *po;
4988 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4989 Py_BEGIN_ALLOW_THREADS
4990 /* PyUnicode_AS_UNICODE OK without thread
4991 lock as it is a simple dereference. */
4992 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4993 Py_END_ALLOW_THREADS
4994 if (fd < 0)
4995 return posix_error();
4996 return PyInt_FromLong((long)fd);
4997 }
4998 /* Drop the argument parsing error as narrow strings
4999 are also valid. */
5000 PyErr_Clear();
5001 }
5002#endif
5003
Tim Peters5aa91602002-01-30 05:46:57 +00005004 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005005 Py_FileSystemDefaultEncoding, &file,
5006 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005007 return NULL;
5008
Barry Warsaw53699e91996-12-10 23:23:01 +00005009 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005010 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005011 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005012 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005013 return posix_error_with_allocated_filename(file);
5014 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005015 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005016}
5017
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005018
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005019PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005020"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005021Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005022
Barry Warsaw53699e91996-12-10 23:23:01 +00005023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005024posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005025{
5026 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005027 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005028 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005029 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005030 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005031 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005032 if (res < 0)
5033 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005034 Py_INCREF(Py_None);
5035 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005036}
5037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005038
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005039PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005040"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005041Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Barry Warsaw53699e91996-12-10 23:23:01 +00005043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005044posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005045{
5046 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005047 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005048 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005049 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005050 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005051 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005052 if (fd < 0)
5053 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005055}
5056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005058PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005059"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005060Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005061
Barry Warsaw53699e91996-12-10 23:23:01 +00005062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005063posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005064{
5065 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005066 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005067 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005068 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005069 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005070 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005071 if (res < 0)
5072 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005073 Py_INCREF(Py_None);
5074 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005075}
5076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005078PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005079"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005081
Barry Warsaw53699e91996-12-10 23:23:01 +00005082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005083posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005084{
5085 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005086#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005087 LONG_LONG pos, res;
5088#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005089 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005090#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005091 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005092 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005093 return NULL;
5094#ifdef SEEK_SET
5095 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5096 switch (how) {
5097 case 0: how = SEEK_SET; break;
5098 case 1: how = SEEK_CUR; break;
5099 case 2: how = SEEK_END; break;
5100 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005101#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005102
5103#if !defined(HAVE_LARGEFILE_SUPPORT)
5104 pos = PyInt_AsLong(posobj);
5105#else
5106 pos = PyLong_Check(posobj) ?
5107 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5108#endif
5109 if (PyErr_Occurred())
5110 return NULL;
5111
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005113#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005114 res = _lseeki64(fd, pos, how);
5115#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005116 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005117#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005118 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005119 if (res < 0)
5120 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005121
5122#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005123 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005124#else
5125 return PyLong_FromLongLong(res);
5126#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005127}
5128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005131"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005132Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005133
Barry Warsaw53699e91996-12-10 23:23:01 +00005134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005136{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005137 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005138 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005139 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005140 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005141 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005142 if (buffer == NULL)
5143 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005144 Py_BEGIN_ALLOW_THREADS
5145 n = read(fd, PyString_AsString(buffer), size);
5146 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005147 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005148 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005149 return posix_error();
5150 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005151 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005152 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005153 return buffer;
5154}
5155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005157PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005158"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005159Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005160
Barry Warsaw53699e91996-12-10 23:23:01 +00005161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005162posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005163{
5164 int fd, size;
5165 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005167 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005168 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005169 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005170 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005171 if (size < 0)
5172 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005173 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005174}
5175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005177PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005178"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005179Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005180
Barry Warsaw53699e91996-12-10 23:23:01 +00005181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005182posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005183{
5184 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005185 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005186 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005188 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005189#ifdef __VMS
5190 /* on OpenVMS we must ensure that all bytes are written to the file */
5191 fsync(fd);
5192#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005193 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005194 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005195 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005196 if (res != 0)
5197 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005198
Fred Drake699f3522000-06-29 21:12:41 +00005199 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005200}
5201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005203PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005204"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005205Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005206
Barry Warsaw53699e91996-12-10 23:23:01 +00005207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005209{
Guido van Rossum687dd131993-05-17 08:34:16 +00005210 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005211 char *mode = "r";
5212 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005213 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005214 PyObject *f;
5215 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005216 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005217
Thomas Heller1f043e22002-11-07 16:00:59 +00005218 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5219 PyErr_Format(PyExc_ValueError,
5220 "invalid file mode '%s'", mode);
5221 return NULL;
5222 }
5223
Barry Warsaw53699e91996-12-10 23:23:01 +00005224 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005225 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005226 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005227 if (fp == NULL)
5228 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005229 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005230 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005231 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005232 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005233}
5234
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005235PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005236"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005237Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005239
5240static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005241posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005242{
5243 int fd;
5244 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5245 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005246 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005247}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005248
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005249#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005250PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005251"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005252Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005253
Barry Warsaw53699e91996-12-10 23:23:01 +00005254static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005255posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005256{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005257#if defined(PYOS_OS2)
5258 HFILE read, write;
5259 APIRET rc;
5260
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005261 Py_BEGIN_ALLOW_THREADS
5262 rc = DosCreatePipe( &read, &write, 4096);
5263 Py_END_ALLOW_THREADS
5264 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005265 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005266
5267 return Py_BuildValue("(ii)", read, write);
5268#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005269#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005270 int fds[2];
5271 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005272 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005273#if defined(__VMS)
5274 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5275#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005276 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005277#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005278 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005279 if (res != 0)
5280 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005281 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005282#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005283 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005284 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005285 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005287 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005288 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005289 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005290 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005291 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5292 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005293 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005294#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005295#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005296}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005297#endif /* HAVE_PIPE */
5298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005299
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005300#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005301PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005302"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005303Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005304
Barry Warsaw53699e91996-12-10 23:23:01 +00005305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005306posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005307{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005308 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005309 int mode = 0666;
5310 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005311 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005312 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005313 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005314 res = mkfifo(filename, mode);
5315 Py_END_ALLOW_THREADS
5316 if (res < 0)
5317 return posix_error();
5318 Py_INCREF(Py_None);
5319 return Py_None;
5320}
5321#endif
5322
5323
Neal Norwitz11690112002-07-30 01:08:28 +00005324#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005326"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005327Create a filesystem node (file, device special file or named pipe)\n\
5328named filename. mode specifies both the permissions to use and the\n\
5329type of node to be created, being combined (bitwise OR) with one of\n\
5330S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005331device defines the newly created device special file (probably using\n\
5332os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005333
5334
5335static PyObject *
5336posix_mknod(PyObject *self, PyObject *args)
5337{
5338 char *filename;
5339 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005340 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005341 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005342 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005343 return NULL;
5344 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005345 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005346 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005347 if (res < 0)
5348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005349 Py_INCREF(Py_None);
5350 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005351}
5352#endif
5353
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005354#ifdef HAVE_DEVICE_MACROS
5355PyDoc_STRVAR(posix_major__doc__,
5356"major(device) -> major number\n\
5357Extracts a device major number from a raw device number.");
5358
5359static PyObject *
5360posix_major(PyObject *self, PyObject *args)
5361{
5362 int device;
5363 if (!PyArg_ParseTuple(args, "i:major", &device))
5364 return NULL;
5365 return PyInt_FromLong((long)major(device));
5366}
5367
5368PyDoc_STRVAR(posix_minor__doc__,
5369"minor(device) -> minor number\n\
5370Extracts a device minor number from a raw device number.");
5371
5372static PyObject *
5373posix_minor(PyObject *self, PyObject *args)
5374{
5375 int device;
5376 if (!PyArg_ParseTuple(args, "i:minor", &device))
5377 return NULL;
5378 return PyInt_FromLong((long)minor(device));
5379}
5380
5381PyDoc_STRVAR(posix_makedev__doc__,
5382"makedev(major, minor) -> device number\n\
5383Composes a raw device number from the major and minor device numbers.");
5384
5385static PyObject *
5386posix_makedev(PyObject *self, PyObject *args)
5387{
5388 int major, minor;
5389 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5390 return NULL;
5391 return PyInt_FromLong((long)makedev(major, minor));
5392}
5393#endif /* device macros */
5394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005395
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005396#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005398"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005402posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005403{
5404 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005405 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005406 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005407 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005408
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005409 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005410 return NULL;
5411
5412#if !defined(HAVE_LARGEFILE_SUPPORT)
5413 length = PyInt_AsLong(lenobj);
5414#else
5415 length = PyLong_Check(lenobj) ?
5416 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5417#endif
5418 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005419 return NULL;
5420
Barry Warsaw53699e91996-12-10 23:23:01 +00005421 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005422 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005423 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005424 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005425 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005426 return NULL;
5427 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005428 Py_INCREF(Py_None);
5429 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005430}
5431#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005432
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005433#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005435"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005436Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005437
Fred Drake762e2061999-08-26 17:23:54 +00005438/* Save putenv() parameters as values here, so we can collect them when they
5439 * get re-set with another call for the same key. */
5440static PyObject *posix_putenv_garbage;
5441
Tim Peters5aa91602002-01-30 05:46:57 +00005442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005443posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005444{
5445 char *s1, *s2;
5446 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005447 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005448 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005449
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005450 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005451 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005452
5453#if defined(PYOS_OS2)
5454 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5455 APIRET rc;
5456
5457 if (strlen(s2) == 0) /* If New Value is an Empty String */
5458 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5459
5460 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5461 if (rc != NO_ERROR)
5462 return os2_error(rc);
5463
5464 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5465 APIRET rc;
5466
5467 if (strlen(s2) == 0) /* If New Value is an Empty String */
5468 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5469
5470 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5471 if (rc != NO_ERROR)
5472 return os2_error(rc);
5473 } else {
5474#endif
5475
Fred Drake762e2061999-08-26 17:23:54 +00005476 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005477 len = strlen(s1) + strlen(s2) + 2;
5478 /* len includes space for a trailing \0; the size arg to
5479 PyString_FromStringAndSize does not count that */
5480 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005481 if (newstr == NULL)
5482 return PyErr_NoMemory();
5483 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005484 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005485 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005486 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005487 posix_error();
5488 return NULL;
5489 }
Fred Drake762e2061999-08-26 17:23:54 +00005490 /* Install the first arg and newstr in posix_putenv_garbage;
5491 * this will cause previous value to be collected. This has to
5492 * happen after the real putenv() call because the old value
5493 * was still accessible until then. */
5494 if (PyDict_SetItem(posix_putenv_garbage,
5495 PyTuple_GET_ITEM(args, 0), newstr)) {
5496 /* really not much we can do; just leak */
5497 PyErr_Clear();
5498 }
5499 else {
5500 Py_DECREF(newstr);
5501 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005502
5503#if defined(PYOS_OS2)
5504 }
5505#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005506 Py_INCREF(Py_None);
5507 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005508}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005509#endif /* putenv */
5510
Guido van Rossumc524d952001-10-19 01:31:59 +00005511#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005513"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005515
5516static PyObject *
5517posix_unsetenv(PyObject *self, PyObject *args)
5518{
5519 char *s1;
5520
5521 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5522 return NULL;
5523
5524 unsetenv(s1);
5525
5526 /* Remove the key from posix_putenv_garbage;
5527 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005528 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005529 * old value was still accessible until then.
5530 */
5531 if (PyDict_DelItem(posix_putenv_garbage,
5532 PyTuple_GET_ITEM(args, 0))) {
5533 /* really not much we can do; just leak */
5534 PyErr_Clear();
5535 }
5536
5537 Py_INCREF(Py_None);
5538 return Py_None;
5539}
5540#endif /* unsetenv */
5541
Guido van Rossumb6a47161997-09-15 22:54:34 +00005542#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005543PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005544"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005545Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005546
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005548posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005549{
5550 int code;
5551 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005553 return NULL;
5554 message = strerror(code);
5555 if (message == NULL) {
5556 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005557 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005558 return NULL;
5559 }
5560 return PyString_FromString(message);
5561}
5562#endif /* strerror */
5563
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005564
Guido van Rossumc9641791998-08-04 15:26:23 +00005565#ifdef HAVE_SYS_WAIT_H
5566
Fred Drake106c1a02002-04-23 15:58:02 +00005567#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005568PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005569"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005571
5572static PyObject *
5573posix_WCOREDUMP(PyObject *self, PyObject *args)
5574{
5575#ifdef UNION_WAIT
5576 union wait status;
5577#define status_i (status.w_status)
5578#else
5579 int status;
5580#define status_i status
5581#endif
5582 status_i = 0;
5583
5584 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5585 {
5586 return NULL;
5587 }
5588
5589 return PyBool_FromLong(WCOREDUMP(status));
5590#undef status_i
5591}
5592#endif /* WCOREDUMP */
5593
5594#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005596"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005597Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005598job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005599
5600static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005601posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005602{
5603#ifdef UNION_WAIT
5604 union wait status;
5605#define status_i (status.w_status)
5606#else
5607 int status;
5608#define status_i status
5609#endif
5610 status_i = 0;
5611
5612 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5613 {
5614 return NULL;
5615 }
5616
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005617 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005618#undef status_i
5619}
5620#endif /* WIFCONTINUED */
5621
Guido van Rossumc9641791998-08-04 15:26:23 +00005622#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005623PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005624"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005625Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005626
5627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005628posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005629{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005630#ifdef UNION_WAIT
5631 union wait status;
5632#define status_i (status.w_status)
5633#else
5634 int status;
5635#define status_i status
5636#endif
5637 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005638
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005639 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005640 {
5641 return NULL;
5642 }
Tim Peters5aa91602002-01-30 05:46:57 +00005643
Fred Drake106c1a02002-04-23 15:58:02 +00005644 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005645#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005646}
5647#endif /* WIFSTOPPED */
5648
5649#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005650PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005651"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005652Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005653
5654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005655posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005656{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005657#ifdef UNION_WAIT
5658 union wait status;
5659#define status_i (status.w_status)
5660#else
5661 int status;
5662#define status_i status
5663#endif
5664 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005666 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005667 {
5668 return NULL;
5669 }
Tim Peters5aa91602002-01-30 05:46:57 +00005670
Fred Drake106c1a02002-04-23 15:58:02 +00005671 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005672#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005673}
5674#endif /* WIFSIGNALED */
5675
5676#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005677PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005678"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005679Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005680system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005681
5682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005683posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005684{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005685#ifdef UNION_WAIT
5686 union wait status;
5687#define status_i (status.w_status)
5688#else
5689 int status;
5690#define status_i status
5691#endif
5692 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005693
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005695 {
5696 return NULL;
5697 }
Tim Peters5aa91602002-01-30 05:46:57 +00005698
Fred Drake106c1a02002-04-23 15:58:02 +00005699 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005701}
5702#endif /* WIFEXITED */
5703
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005704#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005705PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005706"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005708
5709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005710posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005711{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005712#ifdef UNION_WAIT
5713 union wait status;
5714#define status_i (status.w_status)
5715#else
5716 int status;
5717#define status_i status
5718#endif
5719 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005720
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005721 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005722 {
5723 return NULL;
5724 }
Tim Peters5aa91602002-01-30 05:46:57 +00005725
Guido van Rossumc9641791998-08-04 15:26:23 +00005726 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005727#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005728}
5729#endif /* WEXITSTATUS */
5730
5731#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005733"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005734Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005736
5737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005738posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005739{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005740#ifdef UNION_WAIT
5741 union wait status;
5742#define status_i (status.w_status)
5743#else
5744 int status;
5745#define status_i status
5746#endif
5747 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005748
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005749 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005750 {
5751 return NULL;
5752 }
Tim Peters5aa91602002-01-30 05:46:57 +00005753
Guido van Rossumc9641791998-08-04 15:26:23 +00005754 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005755#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005756}
5757#endif /* WTERMSIG */
5758
5759#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005761"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005762Return the signal that stopped the process that provided\n\
5763the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005764
5765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005766posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005767{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005768#ifdef UNION_WAIT
5769 union wait status;
5770#define status_i (status.w_status)
5771#else
5772 int status;
5773#define status_i status
5774#endif
5775 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005776
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005777 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005778 {
5779 return NULL;
5780 }
Tim Peters5aa91602002-01-30 05:46:57 +00005781
Guido van Rossumc9641791998-08-04 15:26:23 +00005782 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005783#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005784}
5785#endif /* WSTOPSIG */
5786
5787#endif /* HAVE_SYS_WAIT_H */
5788
5789
Guido van Rossum94f6f721999-01-06 18:42:14 +00005790#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005791#ifdef _SCO_DS
5792/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5793 needed definitions in sys/statvfs.h */
5794#define _SVID3
5795#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005796#include <sys/statvfs.h>
5797
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005798static PyObject*
5799_pystatvfs_fromstructstatvfs(struct statvfs st) {
5800 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5801 if (v == NULL)
5802 return NULL;
5803
5804#if !defined(HAVE_LARGEFILE_SUPPORT)
5805 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5806 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5807 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5808 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5809 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5810 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5811 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5812 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5813 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5814 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5815#else
5816 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5817 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005818 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005819 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005820 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005821 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5822 PyStructSequence_SET_ITEM(v, 4,
5823 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005824 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005825 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005826 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005827 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005828 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005829 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5830 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5831 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5832#endif
5833
5834 return v;
5835}
5836
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005838"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005840
5841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005842posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005843{
5844 int fd, res;
5845 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005846
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005847 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005848 return NULL;
5849 Py_BEGIN_ALLOW_THREADS
5850 res = fstatvfs(fd, &st);
5851 Py_END_ALLOW_THREADS
5852 if (res != 0)
5853 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005854
5855 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005856}
5857#endif /* HAVE_FSTATVFS */
5858
5859
5860#if defined(HAVE_STATVFS)
5861#include <sys/statvfs.h>
5862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005864"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005866
5867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005868posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005869{
5870 char *path;
5871 int res;
5872 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005873 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005874 return NULL;
5875 Py_BEGIN_ALLOW_THREADS
5876 res = statvfs(path, &st);
5877 Py_END_ALLOW_THREADS
5878 if (res != 0)
5879 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005880
5881 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005882}
5883#endif /* HAVE_STATVFS */
5884
5885
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005886#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005887PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005888"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005889Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005890The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005892
5893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005894posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005895{
5896 PyObject *result = NULL;
5897 char *dir = NULL;
5898 char *pfx = NULL;
5899 char *name;
5900
5901 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5902 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005903
5904 if (PyErr_Warn(PyExc_RuntimeWarning,
5905 "tempnam is a potential security risk to your program") < 0)
5906 return NULL;
5907
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005908#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005909 name = _tempnam(dir, pfx);
5910#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005911 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005912#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005913 if (name == NULL)
5914 return PyErr_NoMemory();
5915 result = PyString_FromString(name);
5916 free(name);
5917 return result;
5918}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005919#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005920
5921
5922#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005923PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005924"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005925Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005926
5927static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005928posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005929{
5930 FILE *fp;
5931
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005932 fp = tmpfile();
5933 if (fp == NULL)
5934 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005935 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005936}
5937#endif
5938
5939
5940#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005942"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005944
5945static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005946posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005947{
5948 char buffer[L_tmpnam];
5949 char *name;
5950
Skip Montanaro95618b52001-08-18 18:52:10 +00005951 if (PyErr_Warn(PyExc_RuntimeWarning,
5952 "tmpnam is a potential security risk to your program") < 0)
5953 return NULL;
5954
Greg Wardb48bc172000-03-01 21:51:56 +00005955#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005956 name = tmpnam_r(buffer);
5957#else
5958 name = tmpnam(buffer);
5959#endif
5960 if (name == NULL) {
5961 PyErr_SetObject(PyExc_OSError,
5962 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005963#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005964 "unexpected NULL from tmpnam_r"
5965#else
5966 "unexpected NULL from tmpnam"
5967#endif
5968 ));
5969 return NULL;
5970 }
5971 return PyString_FromString(buffer);
5972}
5973#endif
5974
5975
Fred Drakec9680921999-12-13 16:37:25 +00005976/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5977 * It maps strings representing configuration variable names to
5978 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005979 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005980 * rarely-used constants. There are three separate tables that use
5981 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005982 *
5983 * This code is always included, even if none of the interfaces that
5984 * need it are included. The #if hackery needed to avoid it would be
5985 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005986 */
5987struct constdef {
5988 char *name;
5989 long value;
5990};
5991
Fred Drake12c6e2d1999-12-14 21:25:03 +00005992static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005993conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5994 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005995{
5996 if (PyInt_Check(arg)) {
5997 *valuep = PyInt_AS_LONG(arg);
5998 return 1;
5999 }
6000 if (PyString_Check(arg)) {
6001 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006002 size_t lo = 0;
6003 size_t mid;
6004 size_t hi = tablesize;
6005 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006006 char *confname = PyString_AS_STRING(arg);
6007 while (lo < hi) {
6008 mid = (lo + hi) / 2;
6009 cmp = strcmp(confname, table[mid].name);
6010 if (cmp < 0)
6011 hi = mid;
6012 else if (cmp > 0)
6013 lo = mid + 1;
6014 else {
6015 *valuep = table[mid].value;
6016 return 1;
6017 }
6018 }
6019 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6020 }
6021 else
6022 PyErr_SetString(PyExc_TypeError,
6023 "configuration names must be strings or integers");
6024 return 0;
6025}
6026
6027
6028#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6029static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006030#ifdef _PC_ABI_AIO_XFER_MAX
6031 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6032#endif
6033#ifdef _PC_ABI_ASYNC_IO
6034 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6035#endif
Fred Drakec9680921999-12-13 16:37:25 +00006036#ifdef _PC_ASYNC_IO
6037 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6038#endif
6039#ifdef _PC_CHOWN_RESTRICTED
6040 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6041#endif
6042#ifdef _PC_FILESIZEBITS
6043 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6044#endif
6045#ifdef _PC_LAST
6046 {"PC_LAST", _PC_LAST},
6047#endif
6048#ifdef _PC_LINK_MAX
6049 {"PC_LINK_MAX", _PC_LINK_MAX},
6050#endif
6051#ifdef _PC_MAX_CANON
6052 {"PC_MAX_CANON", _PC_MAX_CANON},
6053#endif
6054#ifdef _PC_MAX_INPUT
6055 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6056#endif
6057#ifdef _PC_NAME_MAX
6058 {"PC_NAME_MAX", _PC_NAME_MAX},
6059#endif
6060#ifdef _PC_NO_TRUNC
6061 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6062#endif
6063#ifdef _PC_PATH_MAX
6064 {"PC_PATH_MAX", _PC_PATH_MAX},
6065#endif
6066#ifdef _PC_PIPE_BUF
6067 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6068#endif
6069#ifdef _PC_PRIO_IO
6070 {"PC_PRIO_IO", _PC_PRIO_IO},
6071#endif
6072#ifdef _PC_SOCK_MAXBUF
6073 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6074#endif
6075#ifdef _PC_SYNC_IO
6076 {"PC_SYNC_IO", _PC_SYNC_IO},
6077#endif
6078#ifdef _PC_VDISABLE
6079 {"PC_VDISABLE", _PC_VDISABLE},
6080#endif
6081};
6082
Fred Drakec9680921999-12-13 16:37:25 +00006083static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006085{
6086 return conv_confname(arg, valuep, posix_constants_pathconf,
6087 sizeof(posix_constants_pathconf)
6088 / sizeof(struct constdef));
6089}
6090#endif
6091
6092#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006093PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006094"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006095Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006097
6098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006099posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006100{
6101 PyObject *result = NULL;
6102 int name, fd;
6103
Fred Drake12c6e2d1999-12-14 21:25:03 +00006104 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6105 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006106 long limit;
6107
6108 errno = 0;
6109 limit = fpathconf(fd, name);
6110 if (limit == -1 && errno != 0)
6111 posix_error();
6112 else
6113 result = PyInt_FromLong(limit);
6114 }
6115 return result;
6116}
6117#endif
6118
6119
6120#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006123Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006125
6126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006127posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006128{
6129 PyObject *result = NULL;
6130 int name;
6131 char *path;
6132
6133 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6134 conv_path_confname, &name)) {
6135 long limit;
6136
6137 errno = 0;
6138 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006139 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006140 if (errno == EINVAL)
6141 /* could be a path or name problem */
6142 posix_error();
6143 else
6144 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006145 }
Fred Drakec9680921999-12-13 16:37:25 +00006146 else
6147 result = PyInt_FromLong(limit);
6148 }
6149 return result;
6150}
6151#endif
6152
6153#ifdef HAVE_CONFSTR
6154static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006155#ifdef _CS_ARCHITECTURE
6156 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6157#endif
6158#ifdef _CS_HOSTNAME
6159 {"CS_HOSTNAME", _CS_HOSTNAME},
6160#endif
6161#ifdef _CS_HW_PROVIDER
6162 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6163#endif
6164#ifdef _CS_HW_SERIAL
6165 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6166#endif
6167#ifdef _CS_INITTAB_NAME
6168 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6169#endif
Fred Drakec9680921999-12-13 16:37:25 +00006170#ifdef _CS_LFS64_CFLAGS
6171 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6172#endif
6173#ifdef _CS_LFS64_LDFLAGS
6174 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6175#endif
6176#ifdef _CS_LFS64_LIBS
6177 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6178#endif
6179#ifdef _CS_LFS64_LINTFLAGS
6180 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6181#endif
6182#ifdef _CS_LFS_CFLAGS
6183 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6184#endif
6185#ifdef _CS_LFS_LDFLAGS
6186 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6187#endif
6188#ifdef _CS_LFS_LIBS
6189 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6190#endif
6191#ifdef _CS_LFS_LINTFLAGS
6192 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6193#endif
Fred Draked86ed291999-12-15 15:34:33 +00006194#ifdef _CS_MACHINE
6195 {"CS_MACHINE", _CS_MACHINE},
6196#endif
Fred Drakec9680921999-12-13 16:37:25 +00006197#ifdef _CS_PATH
6198 {"CS_PATH", _CS_PATH},
6199#endif
Fred Draked86ed291999-12-15 15:34:33 +00006200#ifdef _CS_RELEASE
6201 {"CS_RELEASE", _CS_RELEASE},
6202#endif
6203#ifdef _CS_SRPC_DOMAIN
6204 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6205#endif
6206#ifdef _CS_SYSNAME
6207 {"CS_SYSNAME", _CS_SYSNAME},
6208#endif
6209#ifdef _CS_VERSION
6210 {"CS_VERSION", _CS_VERSION},
6211#endif
Fred Drakec9680921999-12-13 16:37:25 +00006212#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6213 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6214#endif
6215#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6216 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6217#endif
6218#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6219 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6220#endif
6221#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6222 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6223#endif
6224#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6225 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6226#endif
6227#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6228 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6229#endif
6230#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6231 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6232#endif
6233#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6234 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6235#endif
6236#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6237 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6238#endif
6239#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6240 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6241#endif
6242#ifdef _CS_XBS5_LP64_OFF64_LIBS
6243 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6244#endif
6245#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6246 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6247#endif
6248#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6249 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6250#endif
6251#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6252 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6253#endif
6254#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6255 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6256#endif
6257#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6258 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6259#endif
Fred Draked86ed291999-12-15 15:34:33 +00006260#ifdef _MIPS_CS_AVAIL_PROCESSORS
6261 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6262#endif
6263#ifdef _MIPS_CS_BASE
6264 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6265#endif
6266#ifdef _MIPS_CS_HOSTID
6267 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6268#endif
6269#ifdef _MIPS_CS_HW_NAME
6270 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6271#endif
6272#ifdef _MIPS_CS_NUM_PROCESSORS
6273 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6274#endif
6275#ifdef _MIPS_CS_OSREL_MAJ
6276 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6277#endif
6278#ifdef _MIPS_CS_OSREL_MIN
6279 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6280#endif
6281#ifdef _MIPS_CS_OSREL_PATCH
6282 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6283#endif
6284#ifdef _MIPS_CS_OS_NAME
6285 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6286#endif
6287#ifdef _MIPS_CS_OS_PROVIDER
6288 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6289#endif
6290#ifdef _MIPS_CS_PROCESSORS
6291 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6292#endif
6293#ifdef _MIPS_CS_SERIAL
6294 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6295#endif
6296#ifdef _MIPS_CS_VENDOR
6297 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6298#endif
Fred Drakec9680921999-12-13 16:37:25 +00006299};
6300
6301static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006302conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006303{
6304 return conv_confname(arg, valuep, posix_constants_confstr,
6305 sizeof(posix_constants_confstr)
6306 / sizeof(struct constdef));
6307}
6308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006309PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006310"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006312
6313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006314posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006315{
6316 PyObject *result = NULL;
6317 int name;
6318 char buffer[64];
6319
6320 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6321 int len = confstr(name, buffer, sizeof(buffer));
6322
Fred Drakec9680921999-12-13 16:37:25 +00006323 errno = 0;
6324 if (len == 0) {
6325 if (errno != 0)
6326 posix_error();
6327 else
6328 result = PyString_FromString("");
6329 }
6330 else {
6331 if (len >= sizeof(buffer)) {
6332 result = PyString_FromStringAndSize(NULL, len);
6333 if (result != NULL)
6334 confstr(name, PyString_AS_STRING(result), len+1);
6335 }
6336 else
6337 result = PyString_FromString(buffer);
6338 }
6339 }
6340 return result;
6341}
6342#endif
6343
6344
6345#ifdef HAVE_SYSCONF
6346static struct constdef posix_constants_sysconf[] = {
6347#ifdef _SC_2_CHAR_TERM
6348 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6349#endif
6350#ifdef _SC_2_C_BIND
6351 {"SC_2_C_BIND", _SC_2_C_BIND},
6352#endif
6353#ifdef _SC_2_C_DEV
6354 {"SC_2_C_DEV", _SC_2_C_DEV},
6355#endif
6356#ifdef _SC_2_C_VERSION
6357 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6358#endif
6359#ifdef _SC_2_FORT_DEV
6360 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6361#endif
6362#ifdef _SC_2_FORT_RUN
6363 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6364#endif
6365#ifdef _SC_2_LOCALEDEF
6366 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6367#endif
6368#ifdef _SC_2_SW_DEV
6369 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6370#endif
6371#ifdef _SC_2_UPE
6372 {"SC_2_UPE", _SC_2_UPE},
6373#endif
6374#ifdef _SC_2_VERSION
6375 {"SC_2_VERSION", _SC_2_VERSION},
6376#endif
Fred Draked86ed291999-12-15 15:34:33 +00006377#ifdef _SC_ABI_ASYNCHRONOUS_IO
6378 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6379#endif
6380#ifdef _SC_ACL
6381 {"SC_ACL", _SC_ACL},
6382#endif
Fred Drakec9680921999-12-13 16:37:25 +00006383#ifdef _SC_AIO_LISTIO_MAX
6384 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6385#endif
Fred Drakec9680921999-12-13 16:37:25 +00006386#ifdef _SC_AIO_MAX
6387 {"SC_AIO_MAX", _SC_AIO_MAX},
6388#endif
6389#ifdef _SC_AIO_PRIO_DELTA_MAX
6390 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6391#endif
6392#ifdef _SC_ARG_MAX
6393 {"SC_ARG_MAX", _SC_ARG_MAX},
6394#endif
6395#ifdef _SC_ASYNCHRONOUS_IO
6396 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6397#endif
6398#ifdef _SC_ATEXIT_MAX
6399 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6400#endif
Fred Draked86ed291999-12-15 15:34:33 +00006401#ifdef _SC_AUDIT
6402 {"SC_AUDIT", _SC_AUDIT},
6403#endif
Fred Drakec9680921999-12-13 16:37:25 +00006404#ifdef _SC_AVPHYS_PAGES
6405 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6406#endif
6407#ifdef _SC_BC_BASE_MAX
6408 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6409#endif
6410#ifdef _SC_BC_DIM_MAX
6411 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6412#endif
6413#ifdef _SC_BC_SCALE_MAX
6414 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6415#endif
6416#ifdef _SC_BC_STRING_MAX
6417 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6418#endif
Fred Draked86ed291999-12-15 15:34:33 +00006419#ifdef _SC_CAP
6420 {"SC_CAP", _SC_CAP},
6421#endif
Fred Drakec9680921999-12-13 16:37:25 +00006422#ifdef _SC_CHARCLASS_NAME_MAX
6423 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6424#endif
6425#ifdef _SC_CHAR_BIT
6426 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6427#endif
6428#ifdef _SC_CHAR_MAX
6429 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6430#endif
6431#ifdef _SC_CHAR_MIN
6432 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6433#endif
6434#ifdef _SC_CHILD_MAX
6435 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6436#endif
6437#ifdef _SC_CLK_TCK
6438 {"SC_CLK_TCK", _SC_CLK_TCK},
6439#endif
6440#ifdef _SC_COHER_BLKSZ
6441 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6442#endif
6443#ifdef _SC_COLL_WEIGHTS_MAX
6444 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6445#endif
6446#ifdef _SC_DCACHE_ASSOC
6447 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6448#endif
6449#ifdef _SC_DCACHE_BLKSZ
6450 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6451#endif
6452#ifdef _SC_DCACHE_LINESZ
6453 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6454#endif
6455#ifdef _SC_DCACHE_SZ
6456 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6457#endif
6458#ifdef _SC_DCACHE_TBLKSZ
6459 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6460#endif
6461#ifdef _SC_DELAYTIMER_MAX
6462 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6463#endif
6464#ifdef _SC_EQUIV_CLASS_MAX
6465 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6466#endif
6467#ifdef _SC_EXPR_NEST_MAX
6468 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6469#endif
6470#ifdef _SC_FSYNC
6471 {"SC_FSYNC", _SC_FSYNC},
6472#endif
6473#ifdef _SC_GETGR_R_SIZE_MAX
6474 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6475#endif
6476#ifdef _SC_GETPW_R_SIZE_MAX
6477 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6478#endif
6479#ifdef _SC_ICACHE_ASSOC
6480 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6481#endif
6482#ifdef _SC_ICACHE_BLKSZ
6483 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6484#endif
6485#ifdef _SC_ICACHE_LINESZ
6486 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6487#endif
6488#ifdef _SC_ICACHE_SZ
6489 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6490#endif
Fred Draked86ed291999-12-15 15:34:33 +00006491#ifdef _SC_INF
6492 {"SC_INF", _SC_INF},
6493#endif
Fred Drakec9680921999-12-13 16:37:25 +00006494#ifdef _SC_INT_MAX
6495 {"SC_INT_MAX", _SC_INT_MAX},
6496#endif
6497#ifdef _SC_INT_MIN
6498 {"SC_INT_MIN", _SC_INT_MIN},
6499#endif
6500#ifdef _SC_IOV_MAX
6501 {"SC_IOV_MAX", _SC_IOV_MAX},
6502#endif
Fred Draked86ed291999-12-15 15:34:33 +00006503#ifdef _SC_IP_SECOPTS
6504 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6505#endif
Fred Drakec9680921999-12-13 16:37:25 +00006506#ifdef _SC_JOB_CONTROL
6507 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6508#endif
Fred Draked86ed291999-12-15 15:34:33 +00006509#ifdef _SC_KERN_POINTERS
6510 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6511#endif
6512#ifdef _SC_KERN_SIM
6513 {"SC_KERN_SIM", _SC_KERN_SIM},
6514#endif
Fred Drakec9680921999-12-13 16:37:25 +00006515#ifdef _SC_LINE_MAX
6516 {"SC_LINE_MAX", _SC_LINE_MAX},
6517#endif
6518#ifdef _SC_LOGIN_NAME_MAX
6519 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6520#endif
6521#ifdef _SC_LOGNAME_MAX
6522 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6523#endif
6524#ifdef _SC_LONG_BIT
6525 {"SC_LONG_BIT", _SC_LONG_BIT},
6526#endif
Fred Draked86ed291999-12-15 15:34:33 +00006527#ifdef _SC_MAC
6528 {"SC_MAC", _SC_MAC},
6529#endif
Fred Drakec9680921999-12-13 16:37:25 +00006530#ifdef _SC_MAPPED_FILES
6531 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6532#endif
6533#ifdef _SC_MAXPID
6534 {"SC_MAXPID", _SC_MAXPID},
6535#endif
6536#ifdef _SC_MB_LEN_MAX
6537 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6538#endif
6539#ifdef _SC_MEMLOCK
6540 {"SC_MEMLOCK", _SC_MEMLOCK},
6541#endif
6542#ifdef _SC_MEMLOCK_RANGE
6543 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6544#endif
6545#ifdef _SC_MEMORY_PROTECTION
6546 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6547#endif
6548#ifdef _SC_MESSAGE_PASSING
6549 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6550#endif
Fred Draked86ed291999-12-15 15:34:33 +00006551#ifdef _SC_MMAP_FIXED_ALIGNMENT
6552 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6553#endif
Fred Drakec9680921999-12-13 16:37:25 +00006554#ifdef _SC_MQ_OPEN_MAX
6555 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6556#endif
6557#ifdef _SC_MQ_PRIO_MAX
6558 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6559#endif
Fred Draked86ed291999-12-15 15:34:33 +00006560#ifdef _SC_NACLS_MAX
6561 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6562#endif
Fred Drakec9680921999-12-13 16:37:25 +00006563#ifdef _SC_NGROUPS_MAX
6564 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6565#endif
6566#ifdef _SC_NL_ARGMAX
6567 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6568#endif
6569#ifdef _SC_NL_LANGMAX
6570 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6571#endif
6572#ifdef _SC_NL_MSGMAX
6573 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6574#endif
6575#ifdef _SC_NL_NMAX
6576 {"SC_NL_NMAX", _SC_NL_NMAX},
6577#endif
6578#ifdef _SC_NL_SETMAX
6579 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6580#endif
6581#ifdef _SC_NL_TEXTMAX
6582 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6583#endif
6584#ifdef _SC_NPROCESSORS_CONF
6585 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6586#endif
6587#ifdef _SC_NPROCESSORS_ONLN
6588 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6589#endif
Fred Draked86ed291999-12-15 15:34:33 +00006590#ifdef _SC_NPROC_CONF
6591 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6592#endif
6593#ifdef _SC_NPROC_ONLN
6594 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6595#endif
Fred Drakec9680921999-12-13 16:37:25 +00006596#ifdef _SC_NZERO
6597 {"SC_NZERO", _SC_NZERO},
6598#endif
6599#ifdef _SC_OPEN_MAX
6600 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6601#endif
6602#ifdef _SC_PAGESIZE
6603 {"SC_PAGESIZE", _SC_PAGESIZE},
6604#endif
6605#ifdef _SC_PAGE_SIZE
6606 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6607#endif
6608#ifdef _SC_PASS_MAX
6609 {"SC_PASS_MAX", _SC_PASS_MAX},
6610#endif
6611#ifdef _SC_PHYS_PAGES
6612 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6613#endif
6614#ifdef _SC_PII
6615 {"SC_PII", _SC_PII},
6616#endif
6617#ifdef _SC_PII_INTERNET
6618 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6619#endif
6620#ifdef _SC_PII_INTERNET_DGRAM
6621 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6622#endif
6623#ifdef _SC_PII_INTERNET_STREAM
6624 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6625#endif
6626#ifdef _SC_PII_OSI
6627 {"SC_PII_OSI", _SC_PII_OSI},
6628#endif
6629#ifdef _SC_PII_OSI_CLTS
6630 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6631#endif
6632#ifdef _SC_PII_OSI_COTS
6633 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6634#endif
6635#ifdef _SC_PII_OSI_M
6636 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6637#endif
6638#ifdef _SC_PII_SOCKET
6639 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6640#endif
6641#ifdef _SC_PII_XTI
6642 {"SC_PII_XTI", _SC_PII_XTI},
6643#endif
6644#ifdef _SC_POLL
6645 {"SC_POLL", _SC_POLL},
6646#endif
6647#ifdef _SC_PRIORITIZED_IO
6648 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6649#endif
6650#ifdef _SC_PRIORITY_SCHEDULING
6651 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6652#endif
6653#ifdef _SC_REALTIME_SIGNALS
6654 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6655#endif
6656#ifdef _SC_RE_DUP_MAX
6657 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6658#endif
6659#ifdef _SC_RTSIG_MAX
6660 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6661#endif
6662#ifdef _SC_SAVED_IDS
6663 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6664#endif
6665#ifdef _SC_SCHAR_MAX
6666 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6667#endif
6668#ifdef _SC_SCHAR_MIN
6669 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6670#endif
6671#ifdef _SC_SELECT
6672 {"SC_SELECT", _SC_SELECT},
6673#endif
6674#ifdef _SC_SEMAPHORES
6675 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6676#endif
6677#ifdef _SC_SEM_NSEMS_MAX
6678 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6679#endif
6680#ifdef _SC_SEM_VALUE_MAX
6681 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6682#endif
6683#ifdef _SC_SHARED_MEMORY_OBJECTS
6684 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6685#endif
6686#ifdef _SC_SHRT_MAX
6687 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6688#endif
6689#ifdef _SC_SHRT_MIN
6690 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6691#endif
6692#ifdef _SC_SIGQUEUE_MAX
6693 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6694#endif
6695#ifdef _SC_SIGRT_MAX
6696 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6697#endif
6698#ifdef _SC_SIGRT_MIN
6699 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6700#endif
Fred Draked86ed291999-12-15 15:34:33 +00006701#ifdef _SC_SOFTPOWER
6702 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6703#endif
Fred Drakec9680921999-12-13 16:37:25 +00006704#ifdef _SC_SPLIT_CACHE
6705 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6706#endif
6707#ifdef _SC_SSIZE_MAX
6708 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6709#endif
6710#ifdef _SC_STACK_PROT
6711 {"SC_STACK_PROT", _SC_STACK_PROT},
6712#endif
6713#ifdef _SC_STREAM_MAX
6714 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6715#endif
6716#ifdef _SC_SYNCHRONIZED_IO
6717 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6718#endif
6719#ifdef _SC_THREADS
6720 {"SC_THREADS", _SC_THREADS},
6721#endif
6722#ifdef _SC_THREAD_ATTR_STACKADDR
6723 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6724#endif
6725#ifdef _SC_THREAD_ATTR_STACKSIZE
6726 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6727#endif
6728#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6729 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6730#endif
6731#ifdef _SC_THREAD_KEYS_MAX
6732 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6733#endif
6734#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6735 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6736#endif
6737#ifdef _SC_THREAD_PRIO_INHERIT
6738 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6739#endif
6740#ifdef _SC_THREAD_PRIO_PROTECT
6741 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6742#endif
6743#ifdef _SC_THREAD_PROCESS_SHARED
6744 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6745#endif
6746#ifdef _SC_THREAD_SAFE_FUNCTIONS
6747 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6748#endif
6749#ifdef _SC_THREAD_STACK_MIN
6750 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6751#endif
6752#ifdef _SC_THREAD_THREADS_MAX
6753 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6754#endif
6755#ifdef _SC_TIMERS
6756 {"SC_TIMERS", _SC_TIMERS},
6757#endif
6758#ifdef _SC_TIMER_MAX
6759 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6760#endif
6761#ifdef _SC_TTY_NAME_MAX
6762 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6763#endif
6764#ifdef _SC_TZNAME_MAX
6765 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6766#endif
6767#ifdef _SC_T_IOV_MAX
6768 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6769#endif
6770#ifdef _SC_UCHAR_MAX
6771 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6772#endif
6773#ifdef _SC_UINT_MAX
6774 {"SC_UINT_MAX", _SC_UINT_MAX},
6775#endif
6776#ifdef _SC_UIO_MAXIOV
6777 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6778#endif
6779#ifdef _SC_ULONG_MAX
6780 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6781#endif
6782#ifdef _SC_USHRT_MAX
6783 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6784#endif
6785#ifdef _SC_VERSION
6786 {"SC_VERSION", _SC_VERSION},
6787#endif
6788#ifdef _SC_WORD_BIT
6789 {"SC_WORD_BIT", _SC_WORD_BIT},
6790#endif
6791#ifdef _SC_XBS5_ILP32_OFF32
6792 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6793#endif
6794#ifdef _SC_XBS5_ILP32_OFFBIG
6795 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6796#endif
6797#ifdef _SC_XBS5_LP64_OFF64
6798 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6799#endif
6800#ifdef _SC_XBS5_LPBIG_OFFBIG
6801 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6802#endif
6803#ifdef _SC_XOPEN_CRYPT
6804 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6805#endif
6806#ifdef _SC_XOPEN_ENH_I18N
6807 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6808#endif
6809#ifdef _SC_XOPEN_LEGACY
6810 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6811#endif
6812#ifdef _SC_XOPEN_REALTIME
6813 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6814#endif
6815#ifdef _SC_XOPEN_REALTIME_THREADS
6816 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6817#endif
6818#ifdef _SC_XOPEN_SHM
6819 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6820#endif
6821#ifdef _SC_XOPEN_UNIX
6822 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6823#endif
6824#ifdef _SC_XOPEN_VERSION
6825 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6826#endif
6827#ifdef _SC_XOPEN_XCU_VERSION
6828 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6829#endif
6830#ifdef _SC_XOPEN_XPG2
6831 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6832#endif
6833#ifdef _SC_XOPEN_XPG3
6834 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6835#endif
6836#ifdef _SC_XOPEN_XPG4
6837 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6838#endif
6839};
6840
6841static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006842conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006843{
6844 return conv_confname(arg, valuep, posix_constants_sysconf,
6845 sizeof(posix_constants_sysconf)
6846 / sizeof(struct constdef));
6847}
6848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006849PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006850"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006851Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006852
6853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006854posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006855{
6856 PyObject *result = NULL;
6857 int name;
6858
6859 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6860 int value;
6861
6862 errno = 0;
6863 value = sysconf(name);
6864 if (value == -1 && errno != 0)
6865 posix_error();
6866 else
6867 result = PyInt_FromLong(value);
6868 }
6869 return result;
6870}
6871#endif
6872
6873
Fred Drakebec628d1999-12-15 18:31:10 +00006874/* This code is used to ensure that the tables of configuration value names
6875 * are in sorted order as required by conv_confname(), and also to build the
6876 * the exported dictionaries that are used to publish information about the
6877 * names available on the host platform.
6878 *
6879 * Sorting the table at runtime ensures that the table is properly ordered
6880 * when used, even for platforms we're not able to test on. It also makes
6881 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006882 */
Fred Drakebec628d1999-12-15 18:31:10 +00006883
6884static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006885cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006886{
6887 const struct constdef *c1 =
6888 (const struct constdef *) v1;
6889 const struct constdef *c2 =
6890 (const struct constdef *) v2;
6891
6892 return strcmp(c1->name, c2->name);
6893}
6894
6895static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006896setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006897 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006898{
Fred Drakebec628d1999-12-15 18:31:10 +00006899 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006900 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006901
6902 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6903 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006904 if (d == NULL)
6905 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006906
Barry Warsaw3155db32000-04-13 15:20:40 +00006907 for (i=0; i < tablesize; ++i) {
6908 PyObject *o = PyInt_FromLong(table[i].value);
6909 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6910 Py_XDECREF(o);
6911 Py_DECREF(d);
6912 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006913 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006914 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006915 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006916 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006917}
6918
Fred Drakebec628d1999-12-15 18:31:10 +00006919/* Return -1 on failure, 0 on success. */
6920static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006921setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006922{
6923#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006924 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006925 sizeof(posix_constants_pathconf)
6926 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006927 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006928 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006929#endif
6930#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006931 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006932 sizeof(posix_constants_confstr)
6933 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006934 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006935 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006936#endif
6937#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006938 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006939 sizeof(posix_constants_sysconf)
6940 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006941 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006942 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006943#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006944 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006945}
Fred Draked86ed291999-12-15 15:34:33 +00006946
6947
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006948PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006949"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006950Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006951in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006952
6953static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006954posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006955{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006956 abort();
6957 /*NOTREACHED*/
6958 Py_FatalError("abort() called from Python code didn't abort!");
6959 return NULL;
6960}
Fred Drakebec628d1999-12-15 18:31:10 +00006961
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006962#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006963PyDoc_STRVAR(win32_startfile__doc__,
6964"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006965\n\
6966This acts like double-clicking the file in Explorer, or giving the file\n\
6967name as an argument to the DOS \"start\" command: the file is opened\n\
6968with whatever application (if any) its extension is associated.\n\
6969\n\
6970startfile returns as soon as the associated application is launched.\n\
6971There is no option to wait for the application to close, and no way\n\
6972to retrieve the application's exit status.\n\
6973\n\
6974The filepath is relative to the current directory. If you want to use\n\
6975an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006976the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006977
6978static PyObject *
6979win32_startfile(PyObject *self, PyObject *args)
6980{
6981 char *filepath;
6982 HINSTANCE rc;
6983 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6984 return NULL;
6985 Py_BEGIN_ALLOW_THREADS
6986 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6987 Py_END_ALLOW_THREADS
6988 if (rc <= (HINSTANCE)32)
6989 return win32_error("startfile", filepath);
6990 Py_INCREF(Py_None);
6991 return Py_None;
6992}
6993#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006994
Martin v. Löwis438b5342002-12-27 10:16:42 +00006995#ifdef HAVE_GETLOADAVG
6996PyDoc_STRVAR(posix_getloadavg__doc__,
6997"getloadavg() -> (float, float, float)\n\n\
6998Return the number of processes in the system run queue averaged over\n\
6999the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7000was unobtainable");
7001
7002static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007003posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007004{
7005 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007006 if (getloadavg(loadavg, 3)!=3) {
7007 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7008 return NULL;
7009 } else
7010 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7011}
7012#endif
7013
7014
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007015static PyMethodDef posix_methods[] = {
7016 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7017#ifdef HAVE_TTYNAME
7018 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7019#endif
7020 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7021 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007022#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007023 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007024#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007025#ifdef HAVE_LCHOWN
7026 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7027#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007028#ifdef HAVE_CHROOT
7029 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7030#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007031#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007032 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007033#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007034#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007035 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007036#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007037 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007038#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007039#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007040#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007042#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007043 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7044 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7045 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007046#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007047 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007048#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007049#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007050 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007051#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007052 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7053 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7054 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007055 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007056#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007057 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007058#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007059#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007060 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007061#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007062 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007063#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007064 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007065#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007066 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7067 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7068 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007069#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007070 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007071#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007072 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007073#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007074 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7075 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007076#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007077#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007078 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7079 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007080#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007081#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007082 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007083#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007084#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007085 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007086#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007087#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007088 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007089#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007090#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007091 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007092#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007093#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007094 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007095#endif /* HAVE_GETEGID */
7096#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007097 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007098#endif /* HAVE_GETEUID */
7099#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007100 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007101#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007102#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007103 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007104#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007105 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007106#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007107 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007108#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007109#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007110 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007111#endif /* HAVE_GETPPID */
7112#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007113 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007114#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007115#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007116 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007117#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007118#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007119 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007120#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007121#ifdef HAVE_KILLPG
7122 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7123#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007124#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007125 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007126#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007127#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007128 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007129#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007130 {"popen2", win32_popen2, METH_VARARGS},
7131 {"popen3", win32_popen3, METH_VARARGS},
7132 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007133 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007134#else
7135#if defined(PYOS_OS2) && defined(PYCC_GCC)
7136 {"popen2", os2emx_popen2, METH_VARARGS},
7137 {"popen3", os2emx_popen3, METH_VARARGS},
7138 {"popen4", os2emx_popen4, METH_VARARGS},
7139#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007141#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007142#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007143 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007144#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007145#ifdef HAVE_SETEUID
7146 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7147#endif /* HAVE_SETEUID */
7148#ifdef HAVE_SETEGID
7149 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7150#endif /* HAVE_SETEGID */
7151#ifdef HAVE_SETREUID
7152 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7153#endif /* HAVE_SETREUID */
7154#ifdef HAVE_SETREGID
7155 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7156#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007157#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007158 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007159#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007160#ifdef HAVE_SETGROUPS
7161 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7162#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007163#ifdef HAVE_GETPGID
7164 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7165#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007167 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007168#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007169#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007170 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007171#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007172#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007173 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007174#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007175#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007176 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007177#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007178#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007180#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007181#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007182 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007183#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007184#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007185 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007186#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007187 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7188 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7189 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7190 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7191 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7192 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7193 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7194 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7195 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007196 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007197#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007198 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007199#endif
7200#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007201 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007202#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007203#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007204 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7205#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007206#ifdef HAVE_DEVICE_MACROS
7207 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7208 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7209 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7210#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007211#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007213#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007214#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007216#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007217#ifdef HAVE_UNSETENV
7218 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7219#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007220#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007221 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007222#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007223#ifdef HAVE_FCHDIR
7224 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7225#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007226#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007227 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007228#endif
7229#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007230 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007231#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007232#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007233#ifdef WCOREDUMP
7234 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7235#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007236#ifdef WIFCONTINUED
7237 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7238#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007239#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007240 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007241#endif /* WIFSTOPPED */
7242#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007243 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007244#endif /* WIFSIGNALED */
7245#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007247#endif /* WIFEXITED */
7248#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007250#endif /* WEXITSTATUS */
7251#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007252 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007253#endif /* WTERMSIG */
7254#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007255 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007256#endif /* WSTOPSIG */
7257#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007258#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007259 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007260#endif
7261#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007262 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007263#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007264#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007265 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007266#endif
7267#ifdef HAVE_TEMPNAM
7268 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7269#endif
7270#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007271 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007272#endif
Fred Drakec9680921999-12-13 16:37:25 +00007273#ifdef HAVE_CONFSTR
7274 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7275#endif
7276#ifdef HAVE_SYSCONF
7277 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7278#endif
7279#ifdef HAVE_FPATHCONF
7280 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7281#endif
7282#ifdef HAVE_PATHCONF
7283 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7284#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007285 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007286#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007287 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7288#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007289#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007290 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007291#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007292 {NULL, NULL} /* Sentinel */
7293};
7294
7295
Barry Warsaw4a342091996-12-19 23:50:02 +00007296static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007297ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007298{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007299 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007300}
7301
Guido van Rossumd48f2521997-12-05 22:19:34 +00007302#if defined(PYOS_OS2)
7303/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007304static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007305{
7306 APIRET rc;
7307 ULONG values[QSV_MAX+1];
7308 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007309 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007310
7311 Py_BEGIN_ALLOW_THREADS
7312 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7313 Py_END_ALLOW_THREADS
7314
7315 if (rc != NO_ERROR) {
7316 os2_error(rc);
7317 return -1;
7318 }
7319
Fred Drake4d1e64b2002-04-15 19:40:07 +00007320 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7321 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7322 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7323 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7324 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7325 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7326 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007327
7328 switch (values[QSV_VERSION_MINOR]) {
7329 case 0: ver = "2.00"; break;
7330 case 10: ver = "2.10"; break;
7331 case 11: ver = "2.11"; break;
7332 case 30: ver = "3.00"; break;
7333 case 40: ver = "4.00"; break;
7334 case 50: ver = "5.00"; break;
7335 default:
Tim Peters885d4572001-11-28 20:27:42 +00007336 PyOS_snprintf(tmp, sizeof(tmp),
7337 "%d-%d", values[QSV_VERSION_MAJOR],
7338 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007339 ver = &tmp[0];
7340 }
7341
7342 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007343 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007344 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007345
7346 /* Add Indicator of Which Drive was Used to Boot the System */
7347 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7348 tmp[1] = ':';
7349 tmp[2] = '\0';
7350
Fred Drake4d1e64b2002-04-15 19:40:07 +00007351 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007352}
7353#endif
7354
Barry Warsaw4a342091996-12-19 23:50:02 +00007355static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007356all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007357{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007358#ifdef F_OK
7359 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007360#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007361#ifdef R_OK
7362 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007363#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007364#ifdef W_OK
7365 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007366#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007367#ifdef X_OK
7368 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007369#endif
Fred Drakec9680921999-12-13 16:37:25 +00007370#ifdef NGROUPS_MAX
7371 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7372#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373#ifdef TMP_MAX
7374 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7375#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007376#ifdef WCONTINUED
7377 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7378#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007379#ifdef WNOHANG
7380 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007381#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007382#ifdef WUNTRACED
7383 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7384#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007385#ifdef O_RDONLY
7386 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7387#endif
7388#ifdef O_WRONLY
7389 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7390#endif
7391#ifdef O_RDWR
7392 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7393#endif
7394#ifdef O_NDELAY
7395 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7396#endif
7397#ifdef O_NONBLOCK
7398 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7399#endif
7400#ifdef O_APPEND
7401 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7402#endif
7403#ifdef O_DSYNC
7404 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7405#endif
7406#ifdef O_RSYNC
7407 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7408#endif
7409#ifdef O_SYNC
7410 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7411#endif
7412#ifdef O_NOCTTY
7413 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7414#endif
7415#ifdef O_CREAT
7416 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7417#endif
7418#ifdef O_EXCL
7419 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7420#endif
7421#ifdef O_TRUNC
7422 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7423#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007424#ifdef O_BINARY
7425 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7426#endif
7427#ifdef O_TEXT
7428 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7429#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007430#ifdef O_LARGEFILE
7431 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7432#endif
7433
Tim Peters5aa91602002-01-30 05:46:57 +00007434/* MS Windows */
7435#ifdef O_NOINHERIT
7436 /* Don't inherit in child processes. */
7437 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7438#endif
7439#ifdef _O_SHORT_LIVED
7440 /* Optimize for short life (keep in memory). */
7441 /* MS forgot to define this one with a non-underscore form too. */
7442 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7443#endif
7444#ifdef O_TEMPORARY
7445 /* Automatically delete when last handle is closed. */
7446 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7447#endif
7448#ifdef O_RANDOM
7449 /* Optimize for random access. */
7450 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7451#endif
7452#ifdef O_SEQUENTIAL
7453 /* Optimize for sequential access. */
7454 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7455#endif
7456
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007457/* GNU extensions. */
7458#ifdef O_DIRECT
7459 /* Direct disk access. */
7460 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7461#endif
7462#ifdef O_DIRECTORY
7463 /* Must be a directory. */
7464 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7465#endif
7466#ifdef O_NOFOLLOW
7467 /* Do not follow links. */
7468 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7469#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007470
Barry Warsaw5676bd12003-01-07 20:57:09 +00007471 /* These come from sysexits.h */
7472#ifdef EX_OK
7473 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007474#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007475#ifdef EX_USAGE
7476 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007477#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007478#ifdef EX_DATAERR
7479 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007480#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007481#ifdef EX_NOINPUT
7482 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007483#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007484#ifdef EX_NOUSER
7485 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007486#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007487#ifdef EX_NOHOST
7488 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007489#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007490#ifdef EX_UNAVAILABLE
7491 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007492#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007493#ifdef EX_SOFTWARE
7494 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007495#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007496#ifdef EX_OSERR
7497 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007498#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007499#ifdef EX_OSFILE
7500 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007501#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007502#ifdef EX_CANTCREAT
7503 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007504#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007505#ifdef EX_IOERR
7506 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007507#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007508#ifdef EX_TEMPFAIL
7509 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007510#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007511#ifdef EX_PROTOCOL
7512 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007513#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007514#ifdef EX_NOPERM
7515 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007516#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007517#ifdef EX_CONFIG
7518 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007519#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007520#ifdef EX_NOTFOUND
7521 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007522#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007523
Guido van Rossum246bc171999-02-01 23:54:31 +00007524#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007525#if defined(PYOS_OS2) && defined(PYCC_GCC)
7526 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7527 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7528 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7529 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7530 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7531 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7532 if (ins(d, "P_PM", (long)P_PM)) return -1;
7533 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7534 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7535 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7536 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7537 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7538 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7539 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7540 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7541 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7542 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7543 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7544 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7545 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7546#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007547 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7548 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7549 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7550 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7551 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007552#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007553#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007554
Guido van Rossumd48f2521997-12-05 22:19:34 +00007555#if defined(PYOS_OS2)
7556 if (insertvalues(d)) return -1;
7557#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007558 return 0;
7559}
7560
7561
Tim Peters5aa91602002-01-30 05:46:57 +00007562#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007563#define INITFUNC initnt
7564#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007565
7566#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007567#define INITFUNC initos2
7568#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007569
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007570#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007571#define INITFUNC initposix
7572#define MODNAME "posix"
7573#endif
7574
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007575PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007576INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007577{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007578 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007579
Fred Drake4d1e64b2002-04-15 19:40:07 +00007580 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007581 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007582 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007583
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007584 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007585 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007586 Py_XINCREF(v);
7587 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007588 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007589 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007590
Fred Drake4d1e64b2002-04-15 19:40:07 +00007591 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007592 return;
7593
Fred Drake4d1e64b2002-04-15 19:40:07 +00007594 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007595 return;
7596
Fred Drake4d1e64b2002-04-15 19:40:07 +00007597 Py_INCREF(PyExc_OSError);
7598 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007599
Guido van Rossumb3d39562000-01-31 18:41:26 +00007600#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007601 if (posix_putenv_garbage == NULL)
7602 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007603#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007604
Guido van Rossum14648392001-12-08 18:02:58 +00007605 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007606 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7607 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7608 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007609 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007610 structseq_new = StatResultType.tp_new;
7611 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007612 Py_INCREF((PyObject*) &StatResultType);
7613 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007614
Guido van Rossum14648392001-12-08 18:02:58 +00007615 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007616 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007617 Py_INCREF((PyObject*) &StatVFSResultType);
7618 PyModule_AddObject(m, "statvfs_result",
7619 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620}