blob: 035bb3657eb54751e3ef7e5d7df17e03f33ea152 [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
Tim Peters11b23062003-04-23 02:39:17 +0000115#define HAVE_FSYNC 1
116#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000117#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000118#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
119/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#else /* all other compilers */
121/* Unix functions that the configure script doesn't check for */
122#define HAVE_EXECV 1
123#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000124#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
125#define HAVE_FORK1 1
126#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_GETCWD 1
128#define HAVE_GETEGID 1
129#define HAVE_GETEUID 1
130#define HAVE_GETGID 1
131#define HAVE_GETPPID 1
132#define HAVE_GETUID 1
133#define HAVE_KILL 1
134#define HAVE_OPENDIR 1
135#define HAVE_PIPE 1
136#define HAVE_POPEN 1
137#define HAVE_SYSTEM 1
138#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000139#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000140#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#endif /* _MSC_VER */
142#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000143#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000145
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000147
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000148#if defined(sun) && !defined(__SVR4)
149/* SunOS 4.1.4 doesn't have prototypes for these: */
150extern int rename(const char *, const char *);
151extern int pclose(FILE *);
152extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000153extern int fsync(int);
154extern int lstat(const char *, struct stat *);
155extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000156#endif
157
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000158#if defined(__sgi)&&_COMPILER_VERSION>=700
159/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
160 (default) */
161extern char *ctermid_r(char *);
162#endif
163
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000164#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000167#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000168#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#endif
174#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int chdir(char *);
176extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000177#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int chdir(const char *);
179extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000180#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000181#ifdef __BORLANDC__
182extern int chmod(const char *, int);
183#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000185#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chown(const char *, uid_t, gid_t);
187extern char *getcwd(char *, int);
188extern char *strerror(int);
189extern int link(const char *, const char *);
190extern int rename(const char *, const char *);
191extern int stat(const char *, struct stat *);
192extern int unlink(const char *);
193extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000196#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000199#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000203
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#ifdef HAVE_UTIME_H
205#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000208#ifdef HAVE_SYS_UTIME_H
209#include <sys/utime.h>
210#define HAVE_UTIME_H /* pretend we do for the rest of this file */
211#endif /* HAVE_SYS_UTIME_H */
212
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#ifdef HAVE_SYS_TIMES_H
214#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000215#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216
217#ifdef HAVE_SYS_PARAM_H
218#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000219#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
221#ifdef HAVE_SYS_UTSNAME_H
222#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#define NAMLEN(dirent) strlen((dirent)->d_name)
228#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000229#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#include <direct.h>
231#define NAMLEN(dirent) strlen((dirent)->d_name)
232#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000235#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000238#endif
239#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#endif
242#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#endif
245#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <direct.h>
249#include <io.h>
250#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000251#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000252#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000254#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000256#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000257#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
Guido van Rossumd48f2521997-12-05 22:19:34 +0000259#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262
Tim Petersbc2e10e2002-03-03 23:17:02 +0000263#ifndef MAXPATHLEN
264#define MAXPATHLEN 1024
265#endif /* MAXPATHLEN */
266
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000267#ifdef UNION_WAIT
268/* Emulate some macros on systems that have a union instead of macros */
269
270#ifndef WIFEXITED
271#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
272#endif
273
274#ifndef WEXITSTATUS
275#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
276#endif
277
278#ifndef WTERMSIG
279#define WTERMSIG(u_wait) ((u_wait).w_termsig)
280#endif
281
282#endif /* UNION_WAIT */
283
Greg Wardb48bc172000-03-01 21:51:56 +0000284/* Don't use the "_r" form if we don't need it (also, won't have a
285 prototype for it, at least on Solaris -- maybe others as well?). */
286#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
287#define USE_CTERMID_R
288#endif
289
290#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
291#define USE_TMPNAM_R
292#endif
293
Fred Drake699f3522000-06-29 21:12:41 +0000294/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000295#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000296#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000297# define STAT _stati64
298# define FSTAT _fstati64
299# define STRUCT_STAT struct _stati64
300#else
301# define STAT stat
302# define FSTAT fstat
303# define STRUCT_STAT struct stat
304#endif
305
Tim Peters11b23062003-04-23 02:39:17 +0000306#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000307#include <sys/mkdev.h>
308#else
309#if defined(MAJOR_IN_SYSMACROS)
310#include <sys/sysmacros.h>
311#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000312#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
313#include <sys/mkdev.h>
314#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000315#endif
Fred Drake699f3522000-06-29 21:12:41 +0000316
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000318#ifdef WITH_NEXT_FRAMEWORK
319/* On Darwin/MacOSX a shared library or framework has no access to
320** environ directly, we must obtain it with _NSGetEnviron().
321*/
322#include <crt_externs.h>
323static char **environ;
324#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000326#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000328#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000329/* add some values to provide a similar environment like POSIX */
Tim Peters11b23062003-04-23 02:39:17 +0000330static
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000331void
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000332vms_add_posix_env(PyObject *d)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000333{
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000334 PyObject *o;
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000335 char* str;
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000336
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000337 str = getenv("LINES");
338 o = Py_BuildValue("s", str);
339 if (o != NULL) {
340 (void)PyDict_SetItemString(d, "LINES", o);
341 Py_DECREF(o);
342 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000343
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000344 str = getenv("COLUMNS");
345 o = Py_BuildValue("s", str);
346 if (o != NULL) {
347 (void)PyDict_SetItemString(d, "COLUMNS", o);
348 Py_DECREF(o);
349 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000350
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000351 str = getenv("USER");
352 o = Py_BuildValue("s", str);
353 if (o != NULL) {
354 (void)PyDict_SetItemString(d, "USERNAME", o);
355 Py_DECREF(o);
356 }
357 o = Py_BuildValue("s", str);
358 if (o != NULL) {
359 (void)PyDict_SetItemString(d, "LOGNAME", o);
360 Py_DECREF(o);
361 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000362
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000363 str = getenv("HOME");
364 o = Py_BuildValue("s", str);
365 if (o != NULL) {
366 (void)PyDict_SetItemString(d, "HOME", o);
367 Py_DECREF(o);
368 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000369
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000370 str = getenv("PATH");
371 o = Py_BuildValue("s", str);
372 if (o != NULL) {
373 (void)PyDict_SetItemString(d, "PATH", o);
374 Py_DECREF(o);
375 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000376 /* OS = "OpenVMS" */
377 o = PyString_FromString ("OpenVMS");
378 if (o != NULL) {
379 (void)PyDict_SetItemString(d, "OS", o);
380 Py_DECREF(o);
381 }
382}
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000383#endif /* __VMS */
384
Barry Warsaw53699e91996-12-10 23:23:01 +0000385static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000386convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387{
Barry Warsaw53699e91996-12-10 23:23:01 +0000388 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000390 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 if (d == NULL)
392 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000393#ifdef WITH_NEXT_FRAMEWORK
394 if (environ == NULL)
395 environ = *_NSGetEnviron();
396#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 if (environ == NULL)
398 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000399 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000400 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000401 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000402 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403 char *p = strchr(*e, '=');
404 if (p == NULL)
405 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000406 k = PyString_FromStringAndSize(*e, (int)(p-*e));
407 if (k == NULL) {
408 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000409 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000410 }
411 v = PyString_FromString(p+1);
412 if (v == NULL) {
413 PyErr_Clear();
414 Py_DECREF(k);
415 continue;
416 }
417 if (PyDict_GetItem(d, k) == NULL) {
418 if (PyDict_SetItem(d, k, v) != 0)
419 PyErr_Clear();
420 }
421 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000422 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000424#if defined(__VMS)
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000425 vms_add_posix_env(d);
426#elif defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000427 {
428 APIRET rc;
429 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
430
431 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000432 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000433 PyObject *v = PyString_FromString(buffer);
434 PyDict_SetItemString(d, "BEGINLIBPATH", v);
435 Py_DECREF(v);
436 }
437 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
438 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
439 PyObject *v = PyString_FromString(buffer);
440 PyDict_SetItemString(d, "ENDLIBPATH", v);
441 Py_DECREF(v);
442 }
443 }
444#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000445 return d;
446}
447
448
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449/* Set a POSIX-specific error from errno, and return NULL */
450
Barry Warsawd58d7641998-07-23 16:14:40 +0000451static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000452posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000453{
Barry Warsawca74da41999-02-09 19:31:45 +0000454 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455}
Barry Warsawd58d7641998-07-23 16:14:40 +0000456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000457posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000458{
Barry Warsawca74da41999-02-09 19:31:45 +0000459 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000460}
461
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000462#ifdef Py_WIN_WIDE_FILENAMES
463static PyObject *
464posix_error_with_unicode_filename(Py_UNICODE* name)
465{
466 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
467}
468#endif /* Py_WIN_WIDE_FILENAMES */
469
470
Mark Hammondef8b6542001-05-13 08:04:26 +0000471static PyObject *
472posix_error_with_allocated_filename(char* name)
473{
474 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
475 PyMem_Free(name);
476 return rc;
477}
478
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000479#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000480static PyObject *
481win32_error(char* function, char* filename)
482{
Mark Hammond33a6da92000-08-15 00:46:38 +0000483 /* XXX We should pass the function name along in the future.
484 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000485 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000486 Windows error object, which is non-trivial.
487 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000488 errno = GetLastError();
489 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000490 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000491 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000492 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000493}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000494
495#ifdef Py_WIN_WIDE_FILENAMES
496static PyObject *
497win32_error_unicode(char* function, Py_UNICODE* filename)
498{
499 /* XXX - see win32_error for comments on 'function' */
500 errno = GetLastError();
501 if (filename)
502 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
503 else
504 return PyErr_SetFromWindowsErr(errno);
505}
506
507static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
508{
509 /* XXX Perhaps we should make this API an alias of
510 PyObject_Unicode() instead ?! */
511 if (PyUnicode_CheckExact(obj)) {
512 Py_INCREF(obj);
513 return obj;
514 }
515 if (PyUnicode_Check(obj)) {
516 /* For a Unicode subtype that's not a Unicode object,
517 return a true Unicode object with the same data. */
518 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
519 PyUnicode_GET_SIZE(obj));
520 }
Tim Peters11b23062003-04-23 02:39:17 +0000521 return PyUnicode_FromEncodedObject(obj,
522 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000523 "strict");
524}
525
526#endif /* Py_WIN_WIDE_FILENAMES */
527
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000528#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529
Guido van Rossumd48f2521997-12-05 22:19:34 +0000530#if defined(PYOS_OS2)
531/**********************************************************************
532 * Helper Function to Trim and Format OS/2 Messages
533 **********************************************************************/
534 static void
535os2_formatmsg(char *msgbuf, int msglen, char *reason)
536{
537 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
538
539 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
540 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
541
542 while (lastc > msgbuf && isspace(*lastc))
543 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
544 }
545
546 /* Add Optional Reason Text */
547 if (reason) {
548 strcat(msgbuf, " : ");
549 strcat(msgbuf, reason);
550 }
551}
552
553/**********************************************************************
554 * Decode an OS/2 Operating System Error Code
555 *
556 * A convenience function to lookup an OS/2 error code and return a
557 * text message we can use to raise a Python exception.
558 *
559 * Notes:
560 * The messages for errors returned from the OS/2 kernel reside in
561 * the file OSO001.MSG in the \OS2 directory hierarchy.
562 *
563 **********************************************************************/
564 static char *
565os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
566{
567 APIRET rc;
568 ULONG msglen;
569
570 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
571 Py_BEGIN_ALLOW_THREADS
572 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
573 errorcode, "oso001.msg", &msglen);
574 Py_END_ALLOW_THREADS
575
576 if (rc == NO_ERROR)
577 os2_formatmsg(msgbuf, msglen, reason);
578 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000579 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000580 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000581
582 return msgbuf;
583}
584
585/* Set an OS/2-specific error and return NULL. OS/2 kernel
586 errors are not in a global variable e.g. 'errno' nor are
587 they congruent with posix error numbers. */
588
589static PyObject * os2_error(int code)
590{
591 char text[1024];
592 PyObject *v;
593
594 os2_strerror(text, sizeof(text), code, "");
595
596 v = Py_BuildValue("(is)", code, text);
597 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000598 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000599 Py_DECREF(v);
600 }
601 return NULL; /* Signal to Python that an Exception is Pending */
602}
603
604#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605
606/* POSIX generic methods */
607
Barry Warsaw53699e91996-12-10 23:23:01 +0000608static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000609posix_fildes(PyObject *fdobj, int (*func)(int))
610{
611 int fd;
612 int res;
613 fd = PyObject_AsFileDescriptor(fdobj);
614 if (fd < 0)
615 return NULL;
616 Py_BEGIN_ALLOW_THREADS
617 res = (*func)(fd);
618 Py_END_ALLOW_THREADS
619 if (res < 0)
620 return posix_error();
621 Py_INCREF(Py_None);
622 return Py_None;
623}
Guido van Rossum21142a01999-01-08 21:05:37 +0000624
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000625#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000626static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000627unicode_file_names(void)
628{
629 static int canusewide = -1;
630 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000631 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000632 the Windows NT family. */
633 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
634 }
635 return canusewide;
636}
637#endif
Tim Peters11b23062003-04-23 02:39:17 +0000638
Guido van Rossum21142a01999-01-08 21:05:37 +0000639static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000640posix_1str(PyObject *args, char *format, int (*func)(const char*),
641 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000642{
Mark Hammondef8b6542001-05-13 08:04:26 +0000643 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000644 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000645#ifdef Py_WIN_WIDE_FILENAMES
646 if (unicode_file_names()) {
647 PyUnicodeObject *po;
648 if (PyArg_ParseTuple(args, wformat, &po)) {
649 Py_BEGIN_ALLOW_THREADS
650 /* PyUnicode_AS_UNICODE OK without thread
651 lock as it is a simple dereference. */
652 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
653 Py_END_ALLOW_THREADS
654 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000655 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000656 Py_INCREF(Py_None);
657 return Py_None;
658 }
659 /* Drop the argument parsing error as narrow
660 strings are also valid. */
661 PyErr_Clear();
662 }
663#else
664 /* Platforms that don't support Unicode filenames
665 shouldn't be passing these extra params */
666 assert(wformat==NULL && wfunc == NULL);
667#endif
668
Tim Peters5aa91602002-01-30 05:46:57 +0000669 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000670 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000671 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000672 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000673 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000674 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000675 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000676 return posix_error_with_allocated_filename(path1);
677 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000678 Py_INCREF(Py_None);
679 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680}
681
Barry Warsaw53699e91996-12-10 23:23:01 +0000682static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000683posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000684 char *format,
685 int (*func)(const char *, const char *),
686 char *wformat,
687 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000688{
Mark Hammondef8b6542001-05-13 08:04:26 +0000689 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000690 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000691#ifdef Py_WIN_WIDE_FILENAMES
692 if (unicode_file_names()) {
693 PyObject *po1;
694 PyObject *po2;
695 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
696 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
697 PyObject *wpath1;
698 PyObject *wpath2;
699 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
700 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
701 if (!wpath1 || !wpath2) {
702 Py_XDECREF(wpath1);
703 Py_XDECREF(wpath2);
704 return NULL;
705 }
706 Py_BEGIN_ALLOW_THREADS
707 /* PyUnicode_AS_UNICODE OK without thread
708 lock as it is a simple dereference. */
709 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
710 PyUnicode_AS_UNICODE(wpath2));
711 Py_END_ALLOW_THREADS
712 Py_XDECREF(wpath1);
713 Py_XDECREF(wpath2);
714 if (res != 0)
715 return posix_error();
716 Py_INCREF(Py_None);
717 return Py_None;
718 }
719 /* Else flow through as neither is Unicode. */
720 }
721 /* Drop the argument parsing error as narrow
722 strings are also valid. */
723 PyErr_Clear();
724 }
725#else
726 /* Platforms that don't support Unicode filenames
727 shouldn't be passing these extra params */
728 assert(wformat==NULL && wfunc == NULL);
729#endif
730
Mark Hammondef8b6542001-05-13 08:04:26 +0000731 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000732 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000733 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000734 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000735 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000736 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000737 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000738 PyMem_Free(path1);
739 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000740 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000741 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000743 Py_INCREF(Py_None);
744 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000745}
746
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000747PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000748"stat_result: Result from stat or lstat.\n\n\
749This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000750 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000751or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
752\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000753Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000754they are available as attributes only.\n\
755\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000756See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000757
758static PyStructSequence_Field stat_result_fields[] = {
759 {"st_mode", "protection bits"},
760 {"st_ino", "inode"},
761 {"st_dev", "device"},
762 {"st_nlink", "number of hard links"},
763 {"st_uid", "user ID of owner"},
764 {"st_gid", "group ID of owner"},
765 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000766 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
767 {NULL, "integer time of last access"},
768 {NULL, "integer time of last modification"},
769 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000770 {"st_atime", "time of last access"},
771 {"st_mtime", "time of last modification"},
772 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000773#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000774 {"st_blksize", "blocksize for filesystem I/O"},
775#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000776#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000777 {"st_blocks", "number of blocks allocated"},
778#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000779#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000780 {"st_rdev", "device type (if inode device)"},
781#endif
782 {0}
783};
784
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000785#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000786#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000787#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000788#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000789#endif
790
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000791#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000792#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
793#else
794#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
795#endif
796
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000797#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000798#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
799#else
800#define ST_RDEV_IDX ST_BLOCKS_IDX
801#endif
802
803static PyStructSequence_Desc stat_result_desc = {
804 "stat_result", /* name */
805 stat_result__doc__, /* doc */
806 stat_result_fields,
807 10
808};
809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000810PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000811"statvfs_result: Result from statvfs or fstatvfs.\n\n\
812This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000813 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000814or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000815\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000816See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000817
818static PyStructSequence_Field statvfs_result_fields[] = {
819 {"f_bsize", },
820 {"f_frsize", },
821 {"f_blocks", },
822 {"f_bfree", },
823 {"f_bavail", },
824 {"f_files", },
825 {"f_ffree", },
826 {"f_favail", },
827 {"f_flag", },
828 {"f_namemax",},
829 {0}
830};
831
832static PyStructSequence_Desc statvfs_result_desc = {
833 "statvfs_result", /* name */
834 statvfs_result__doc__, /* doc */
835 statvfs_result_fields,
836 10
837};
838
839static PyTypeObject StatResultType;
840static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000841static newfunc structseq_new;
842
843static PyObject *
844statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
845{
846 PyStructSequence *result;
847 int i;
848
849 result = (PyStructSequence*)structseq_new(type, args, kwds);
850 if (!result)
851 return NULL;
852 /* If we have been initialized from a tuple,
853 st_?time might be set to None. Initialize it
854 from the int slots. */
855 for (i = 7; i <= 9; i++) {
856 if (result->ob_item[i+3] == Py_None) {
857 Py_DECREF(Py_None);
858 Py_INCREF(result->ob_item[i]);
859 result->ob_item[i+3] = result->ob_item[i];
860 }
861 }
862 return (PyObject*)result;
863}
864
865
866
867/* If true, st_?time is float. */
868static int _stat_float_times = 0;
869
870PyDoc_STRVAR(stat_float_times__doc__,
871"stat_float_times([newval]) -> oldval\n\n\
872Determine whether os.[lf]stat represents time stamps as float objects.\n\
873If newval is True, future calls to stat() return floats, if it is False,\n\
874future calls return ints. \n\
875If newval is omitted, return the current setting.\n");
876
877static PyObject*
878stat_float_times(PyObject* self, PyObject *args)
879{
880 int newval = -1;
881 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
882 return NULL;
883 if (newval == -1)
884 /* Return old value */
885 return PyBool_FromLong(_stat_float_times);
886 _stat_float_times = newval;
887 Py_INCREF(Py_None);
888 return Py_None;
889}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000890
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000891static void
892fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
893{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000894 PyObject *fval,*ival;
895#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000896 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000897#else
898 ival = PyInt_FromLong((long)sec);
899#endif
900 if (_stat_float_times) {
901 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
902 } else {
903 fval = ival;
904 Py_INCREF(fval);
905 }
906 PyStructSequence_SET_ITEM(v, index, ival);
907 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000908}
909
Tim Peters5aa91602002-01-30 05:46:57 +0000910/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000911 (used by posix_stat() and posix_fstat()) */
912static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000913_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000914{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000915 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000916 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000917 if (v == NULL)
918 return NULL;
919
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000920 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000921#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000922 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000923 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000924#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000925 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000926#endif
927#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000928 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000929 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000930#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000932#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000933 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
934 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
935 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000936#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000937 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000938 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000939#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000940 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000941#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000942
943#ifdef HAVE_STAT_TV_NSEC
944 ansec = st.st_atim.tv_nsec;
945 mnsec = st.st_mtim.tv_nsec;
946 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000947#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000948 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000949#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000950 fill_time(v, 7, st.st_atime, ansec);
951 fill_time(v, 8, st.st_mtime, mnsec);
952 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000953
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000954#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000955 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000956 PyInt_FromLong((long)st.st_blksize));
957#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000958#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000959 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000960 PyInt_FromLong((long)st.st_blocks));
961#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000962#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000963 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
964 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000965#endif
966
967 if (PyErr_Occurred()) {
968 Py_DECREF(v);
969 return NULL;
970 }
971
972 return v;
973}
974
Barry Warsaw53699e91996-12-10 23:23:01 +0000975static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000976posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000977 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000978#ifdef __VMS
979 int (*statfunc)(const char *, STRUCT_STAT *, ...),
980#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000981 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000982#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000983 char *wformat,
984 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985{
Fred Drake699f3522000-06-29 21:12:41 +0000986 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000987 char *path = NULL; /* pass this to stat; do not free() it */
988 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000989 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000990
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000991#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000992 int pathlen;
993 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000994#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000995
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000996
997#ifdef Py_WIN_WIDE_FILENAMES
998 /* If on wide-character-capable OS see if argument
999 is Unicode and if so use wide API. */
1000 if (unicode_file_names()) {
1001 PyUnicodeObject *po;
1002 if (PyArg_ParseTuple(args, wformat, &po)) {
1003 Py_UNICODE wpath[MAX_PATH+1];
1004 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1005 /* the library call can blow up if the file name is too long! */
1006 if (pathlen > MAX_PATH) {
1007 errno = ENAMETOOLONG;
1008 return posix_error();
1009 }
1010 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1011 /* Remove trailing slash or backslash, unless it's the current
1012 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1013 */
1014 if (pathlen > 0 &&
1015 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1016 /* It does end with a slash -- exempt the root drive cases. */
1017 /* XXX UNC root drives should also be exempted? */
1018 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1019 /* leave it alone */;
1020 else {
1021 /* nuke the trailing backslash */
1022 wpath[pathlen-1] = L'\0';
1023 }
1024 }
1025 Py_BEGIN_ALLOW_THREADS
1026 /* PyUnicode_AS_UNICODE result OK without
1027 thread lock as it is a simple dereference. */
1028 res = wstatfunc(wpath, &st);
1029 Py_END_ALLOW_THREADS
1030 if (res != 0)
1031 return posix_error_with_unicode_filename(wpath);
1032 return _pystat_fromstructstat(st);
1033 }
1034 /* Drop the argument parsing error as narrow strings
1035 are also valid. */
1036 PyErr_Clear();
1037 }
1038#endif
1039
Tim Peters5aa91602002-01-30 05:46:57 +00001040 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001041 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001042 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001043 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001044
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001045#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001046 pathlen = strlen(path);
1047 /* the library call can blow up if the file name is too long! */
1048 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001049 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001050 errno = ENAMETOOLONG;
1051 return posix_error();
1052 }
1053
Tim Peters500bd032001-12-19 19:05:01 +00001054 /* Remove trailing slash or backslash, unless it's the current
1055 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1056 */
1057 if (pathlen > 0 &&
1058 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1059 /* It does end with a slash -- exempt the root drive cases. */
1060 /* XXX UNC root drives should also be exempted? */
1061 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1062 /* leave it alone */;
1063 else {
1064 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001065 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001066 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001067 path = pathcopy;
1068 }
1069 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001070#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001071
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001073 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001074 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001075 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001076 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001077
Tim Peters500bd032001-12-19 19:05:01 +00001078 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001079 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001080}
1081
1082
1083/* POSIX methods */
1084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001085PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001086"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001087Use the real uid/gid to test for access to a path. Note that most\n\
1088operations will use the effective uid/gid, therefore this routine can\n\
1089be used in a suid/sgid environment to test if the invoking user has the\n\
1090specified access to the path. The mode argument can be F_OK to test\n\
1091existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001092
1093static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001094posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001095{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001096 char *path;
1097 int mode;
1098 int res;
1099
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001100 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001101 return NULL;
1102 Py_BEGIN_ALLOW_THREADS
1103 res = access(path, mode);
1104 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001105 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001106}
1107
Guido van Rossumd371ff11999-01-25 16:12:23 +00001108#ifndef F_OK
1109#define F_OK 0
1110#endif
1111#ifndef R_OK
1112#define R_OK 4
1113#endif
1114#ifndef W_OK
1115#define W_OK 2
1116#endif
1117#ifndef X_OK
1118#define X_OK 1
1119#endif
1120
1121#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001123"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001124Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001125
1126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001127posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001128{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001129 int id;
1130 char *ret;
1131
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001132 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001133 return NULL;
1134
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001135#if defined(__VMS)
1136 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1137 if (id == 0) {
1138 ret = ttyname();
1139 }
1140 else {
1141 ret = NULL;
1142 }
1143#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001144 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001145#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001146 if (ret == NULL)
1147 return(posix_error());
1148 return(PyString_FromString(ret));
1149}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001150#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001151
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001152#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001154"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001155Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001156
1157static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001158posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001159{
1160 char *ret;
1161 char buffer[L_ctermid];
1162
Greg Wardb48bc172000-03-01 21:51:56 +00001163#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001164 ret = ctermid_r(buffer);
1165#else
1166 ret = ctermid(buffer);
1167#endif
1168 if (ret == NULL)
1169 return(posix_error());
1170 return(PyString_FromString(buffer));
1171}
1172#endif
1173
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001175"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001176Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001177
Barry Warsaw53699e91996-12-10 23:23:01 +00001178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001179posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001180{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001181#ifdef MS_WINDOWS
1182 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1183#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1184 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001185#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001186 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001187 NULL, NULL);
1188#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001189 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001190#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191}
1192
Fred Drake4d1e64b2002-04-15 19:40:07 +00001193#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001194PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001195"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001196Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001197opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001198
1199static PyObject *
1200posix_fchdir(PyObject *self, PyObject *fdobj)
1201{
1202 return posix_fildes(fdobj, fchdir);
1203}
1204#endif /* HAVE_FCHDIR */
1205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001208"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001209Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001210
Barry Warsaw53699e91996-12-10 23:23:01 +00001211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001212posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213{
Mark Hammondef8b6542001-05-13 08:04:26 +00001214 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001215 int i;
1216 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001217 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001218 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001219 return NULL;
1220 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001221 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001222 Py_END_ALLOW_THREADS
1223 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001224 return posix_error_with_allocated_filename(path);
1225 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001226 Py_INCREF(Py_None);
1227 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228}
1229
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001230
Martin v. Löwis244edc82001-10-04 22:44:26 +00001231#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001233"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001234Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001235
1236static PyObject *
1237posix_chroot(PyObject *self, PyObject *args)
1238{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001240}
1241#endif
1242
Guido van Rossum21142a01999-01-08 21:05:37 +00001243#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001245"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001246force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001247
1248static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001249posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001250{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001251 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001252}
1253#endif /* HAVE_FSYNC */
1254
1255#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001256
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001257#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001258extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1259#endif
1260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001261PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001262"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001263force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001264 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001265
1266static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001267posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001268{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001269 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001270}
1271#endif /* HAVE_FDATASYNC */
1272
1273
Fredrik Lundh10723342000-07-10 16:38:09 +00001274#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001276"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278
Barry Warsaw53699e91996-12-10 23:23:01 +00001279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001280posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001281{
Mark Hammondef8b6542001-05-13 08:04:26 +00001282 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001283 int uid, gid;
1284 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001285 if (!PyArg_ParseTuple(args, "etii:chown",
1286 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001287 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001288 return NULL;
1289 Py_BEGIN_ALLOW_THREADS
1290 res = chown(path, (uid_t) uid, (gid_t) gid);
1291 Py_END_ALLOW_THREADS
1292 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001293 return posix_error_with_allocated_filename(path);
1294 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001295 Py_INCREF(Py_None);
1296 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001298#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001299
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001300#ifdef HAVE_LCHOWN
1301PyDoc_STRVAR(posix_lchown__doc__,
1302"lchown(path, uid, gid)\n\n\
1303Change the owner and group id of path to the numeric uid and gid.\n\
1304This function will not follow symbolic links.");
1305
1306static PyObject *
1307posix_lchown(PyObject *self, PyObject *args)
1308{
1309 char *path = NULL;
1310 int uid, gid;
1311 int res;
1312 if (!PyArg_ParseTuple(args, "etii:lchown",
1313 Py_FileSystemDefaultEncoding, &path,
1314 &uid, &gid))
1315 return NULL;
1316 Py_BEGIN_ALLOW_THREADS
1317 res = lchown(path, (uid_t) uid, (gid_t) gid);
1318 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001319 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001320 return posix_error_with_allocated_filename(path);
1321 PyMem_Free(path);
1322 Py_INCREF(Py_None);
1323 return Py_None;
1324}
1325#endif /* HAVE_LCHOWN */
1326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001327
Guido van Rossum36bc6801995-06-14 22:54:23 +00001328#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001330"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001331Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
Barry Warsaw53699e91996-12-10 23:23:01 +00001333static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001334posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335{
1336 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001337 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001340#if defined(PYOS_OS2) && defined(PYCC_GCC)
1341 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001342#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001343 /* 0 = force Unix-style path if in the VMS DCL environment! */
1344 res = getcwd(buf, sizeof buf, 0);
1345#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001346 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001347#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001348 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001349 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001351 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001352}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001353
Walter Dörwald3b918c32002-11-21 20:18:46 +00001354#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001355PyDoc_STRVAR(posix_getcwdu__doc__,
1356"getcwdu() -> path\n\n\
1357Return a unicode string representing the current working directory.");
1358
1359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001360posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001361{
1362 char buf[1026];
1363 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001364
1365#ifdef Py_WIN_WIDE_FILENAMES
1366 if (unicode_file_names()) {
1367 wchar_t *wres;
1368 wchar_t wbuf[1026];
1369 Py_BEGIN_ALLOW_THREADS
1370 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1371 Py_END_ALLOW_THREADS
1372 if (wres == NULL)
1373 return posix_error();
1374 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1375 }
1376#endif
1377
1378 Py_BEGIN_ALLOW_THREADS
1379#if defined(PYOS_OS2) && defined(PYCC_GCC)
1380 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001381#elif defined(__VMS)
1382 /* 0 = force Unix-style path if in the VMS DCL environment! */
1383 res = getcwd(buf, sizeof buf, 0);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001384#else
1385 res = getcwd(buf, sizeof buf);
1386#endif
1387 Py_END_ALLOW_THREADS
1388 if (res == NULL)
1389 return posix_error();
1390 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1391}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001392#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001393#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001394
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001395
Guido van Rossumb6775db1994-08-01 11:34:53 +00001396#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001398"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001399Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
Barry Warsaw53699e91996-12-10 23:23:01 +00001401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001402posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001404 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001406#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001409PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001410"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001411Return a list containing the names of the entries in the directory.\n\
1412\n\
1413 path: path of directory to list\n\
1414\n\
1415The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001416entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001417
Barry Warsaw53699e91996-12-10 23:23:01 +00001418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001419posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001420{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001421 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001422 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001423#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001424
Barry Warsaw53699e91996-12-10 23:23:01 +00001425 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001426 HANDLE hFindFile;
1427 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001428 /* MAX_PATH characters could mean a bigger encoded string */
1429 char namebuf[MAX_PATH*2+5];
1430 char *bufptr = namebuf;
1431 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001432
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001433#ifdef Py_WIN_WIDE_FILENAMES
1434 /* If on wide-character-capable OS see if argument
1435 is Unicode and if so use wide API. */
1436 if (unicode_file_names()) {
1437 PyUnicodeObject *po;
1438 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1439 WIN32_FIND_DATAW wFileData;
1440 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1441 Py_UNICODE wch;
1442 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1443 wnamebuf[MAX_PATH] = L'\0';
1444 len = wcslen(wnamebuf);
1445 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1446 if (wch != L'/' && wch != L'\\' && wch != L':')
1447 wnamebuf[len++] = L'/';
1448 wcscpy(wnamebuf + len, L"*.*");
1449 if ((d = PyList_New(0)) == NULL)
1450 return NULL;
1451 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1452 if (hFindFile == INVALID_HANDLE_VALUE) {
1453 errno = GetLastError();
1454 if (errno == ERROR_FILE_NOT_FOUND) {
1455 return d;
1456 }
1457 Py_DECREF(d);
1458 return win32_error_unicode("FindFirstFileW", wnamebuf);
1459 }
1460 do {
1461 if (wFileData.cFileName[0] == L'.' &&
1462 (wFileData.cFileName[1] == L'\0' ||
1463 wFileData.cFileName[1] == L'.' &&
1464 wFileData.cFileName[2] == L'\0'))
1465 continue;
1466 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1467 if (v == NULL) {
1468 Py_DECREF(d);
1469 d = NULL;
1470 break;
1471 }
1472 if (PyList_Append(d, v) != 0) {
1473 Py_DECREF(v);
1474 Py_DECREF(d);
1475 d = NULL;
1476 break;
1477 }
1478 Py_DECREF(v);
1479 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1480
1481 if (FindClose(hFindFile) == FALSE) {
1482 Py_DECREF(d);
1483 return win32_error_unicode("FindClose", wnamebuf);
1484 }
1485 return d;
1486 }
1487 /* Drop the argument parsing error as narrow strings
1488 are also valid. */
1489 PyErr_Clear();
1490 }
1491#endif
1492
Tim Peters5aa91602002-01-30 05:46:57 +00001493 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001494 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001495 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001496 if (len > 0) {
1497 char ch = namebuf[len-1];
1498 if (ch != SEP && ch != ALTSEP && ch != ':')
1499 namebuf[len++] = '/';
1500 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001501 strcpy(namebuf + len, "*.*");
1502
Barry Warsaw53699e91996-12-10 23:23:01 +00001503 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001504 return NULL;
1505
1506 hFindFile = FindFirstFile(namebuf, &FileData);
1507 if (hFindFile == INVALID_HANDLE_VALUE) {
1508 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001509 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001510 return d;
1511 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001512 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001513 }
1514 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001515 if (FileData.cFileName[0] == '.' &&
1516 (FileData.cFileName[1] == '\0' ||
1517 FileData.cFileName[1] == '.' &&
1518 FileData.cFileName[2] == '\0'))
1519 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001522 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001523 d = NULL;
1524 break;
1525 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001526 if (PyList_Append(d, v) != 0) {
1527 Py_DECREF(v);
1528 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001529 d = NULL;
1530 break;
1531 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001532 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001533 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1534
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001535 if (FindClose(hFindFile) == FALSE) {
1536 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001537 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001538 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001539
1540 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001541
Tim Peters0bb44a42000-09-15 07:44:49 +00001542#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001543
1544#ifndef MAX_PATH
1545#define MAX_PATH CCHMAXPATH
1546#endif
1547 char *name, *pt;
1548 int len;
1549 PyObject *d, *v;
1550 char namebuf[MAX_PATH+5];
1551 HDIR hdir = 1;
1552 ULONG srchcnt = 1;
1553 FILEFINDBUF3 ep;
1554 APIRET rc;
1555
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001556 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001557 return NULL;
1558 if (len >= MAX_PATH) {
1559 PyErr_SetString(PyExc_ValueError, "path too long");
1560 return NULL;
1561 }
1562 strcpy(namebuf, name);
1563 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001564 if (*pt == ALTSEP)
1565 *pt = SEP;
1566 if (namebuf[len-1] != SEP)
1567 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001568 strcpy(namebuf + len, "*.*");
1569
1570 if ((d = PyList_New(0)) == NULL)
1571 return NULL;
1572
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001573 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1574 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001575 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001576 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1577 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1578 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001579
1580 if (rc != NO_ERROR) {
1581 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001582 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001583 }
1584
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001585 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001586 do {
1587 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001588 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001589 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001590
1591 strcpy(namebuf, ep.achName);
1592
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001593 /* Leave Case of Name Alone -- In Native Form */
1594 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001595
1596 v = PyString_FromString(namebuf);
1597 if (v == NULL) {
1598 Py_DECREF(d);
1599 d = NULL;
1600 break;
1601 }
1602 if (PyList_Append(d, v) != 0) {
1603 Py_DECREF(v);
1604 Py_DECREF(d);
1605 d = NULL;
1606 break;
1607 }
1608 Py_DECREF(v);
1609 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1610 }
1611
1612 return d;
1613#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001614
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001615 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001616 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001618 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001619 int arg_is_unicode = 1;
1620
1621 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1622 arg_is_unicode = 0;
1623 PyErr_Clear();
1624 }
1625 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001626 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001627 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001628 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001629 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001632 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633 return NULL;
1634 }
1635 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001636 if (ep->d_name[0] == '.' &&
1637 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001638 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001639 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001642 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001643 d = NULL;
1644 break;
1645 }
Just van Rossum46c97842003-02-25 21:42:15 +00001646#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001647 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001648 PyObject *w;
1649
1650 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001651 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001652 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001653 if (w != NULL) {
1654 Py_DECREF(v);
1655 v = w;
1656 }
1657 else {
1658 /* fall back to the original byte string, as
1659 discussed in patch #683592 */
1660 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001661 }
Just van Rossum46c97842003-02-25 21:42:15 +00001662 }
1663#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001664 if (PyList_Append(d, v) != 0) {
1665 Py_DECREF(v);
1666 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001667 d = NULL;
1668 break;
1669 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001670 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001671 }
1672 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001673 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001674
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001675 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001676
Tim Peters0bb44a42000-09-15 07:44:49 +00001677#endif /* which OS */
1678} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001679
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001680#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001681/* A helper function for abspath on win32 */
1682static PyObject *
1683posix__getfullpathname(PyObject *self, PyObject *args)
1684{
1685 /* assume encoded strings wont more than double no of chars */
1686 char inbuf[MAX_PATH*2];
1687 char *inbufp = inbuf;
1688 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1689 char outbuf[MAX_PATH*2];
1690 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001691#ifdef Py_WIN_WIDE_FILENAMES
1692 if (unicode_file_names()) {
1693 PyUnicodeObject *po;
1694 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1695 Py_UNICODE woutbuf[MAX_PATH*2];
1696 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001697 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001698 sizeof(woutbuf)/sizeof(woutbuf[0]),
1699 woutbuf, &wtemp))
1700 return win32_error("GetFullPathName", "");
1701 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1702 }
1703 /* Drop the argument parsing error as narrow strings
1704 are also valid. */
1705 PyErr_Clear();
1706 }
1707#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001708 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1709 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001710 &insize))
1711 return NULL;
1712 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1713 outbuf, &temp))
1714 return win32_error("GetFullPathName", inbuf);
1715 return PyString_FromString(outbuf);
1716} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001717#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001720"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001721Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001722
Barry Warsaw53699e91996-12-10 23:23:01 +00001723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001724posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001725{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001726 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001727 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001728 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001729
1730#ifdef Py_WIN_WIDE_FILENAMES
1731 if (unicode_file_names()) {
1732 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001733 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001734 Py_BEGIN_ALLOW_THREADS
1735 /* PyUnicode_AS_UNICODE OK without thread lock as
1736 it is a simple dereference. */
1737 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1738 Py_END_ALLOW_THREADS
1739 if (res < 0)
1740 return posix_error();
1741 Py_INCREF(Py_None);
1742 return Py_None;
1743 }
1744 /* Drop the argument parsing error as narrow strings
1745 are also valid. */
1746 PyErr_Clear();
1747 }
1748#endif
1749
Tim Peters5aa91602002-01-30 05:46:57 +00001750 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001751 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001752 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001753 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001754#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001755 res = mkdir(path);
1756#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001757 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001758#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001759 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001760 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001761 return posix_error_with_allocated_filename(path);
1762 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001763 Py_INCREF(Py_None);
1764 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001765}
1766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767
Guido van Rossumb6775db1994-08-01 11:34:53 +00001768#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001769#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1770#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1771#include <sys/resource.h>
1772#endif
1773#endif
1774
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001776"nice(inc) -> new_priority\n\n\
1777Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001778
Barry Warsaw53699e91996-12-10 23:23:01 +00001779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001780posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001781{
1782 int increment, value;
1783
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001784 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001785 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001786
1787 /* There are two flavours of 'nice': one that returns the new
1788 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001789 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1790 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001791
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001792 If we are of the nice family that returns the new priority, we
1793 need to clear errno before the call, and check if errno is filled
1794 before calling posix_error() on a returnvalue of -1, because the
1795 -1 may be the actual new priority! */
1796
1797 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001798 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001799#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001800 if (value == 0)
1801 value = getpriority(PRIO_PROCESS, 0);
1802#endif
1803 if (value == -1 && errno != 0)
1804 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001805 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001806 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001807}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001808#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001812"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001814
Barry Warsaw53699e91996-12-10 23:23:01 +00001815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001817{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001818#ifdef MS_WINDOWS
1819 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1820#else
1821 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1822#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001823}
1824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001825
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001827"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001828Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001829
Barry Warsaw53699e91996-12-10 23:23:01 +00001830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001831posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001832{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001833#ifdef MS_WINDOWS
1834 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1835#else
1836 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1837#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001838}
1839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001840
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001842"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001843Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001844
Barry Warsaw53699e91996-12-10 23:23:01 +00001845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001846posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001848#ifdef MS_WINDOWS
1849 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1850#else
1851 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1852#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001853}
1854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001856#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860
Barry Warsaw53699e91996-12-10 23:23:01 +00001861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001863{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001864 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001865 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001866 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001867 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001869 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001870 Py_END_ALLOW_THREADS
1871 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001872}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001873#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001877"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001881posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001882{
1883 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001884 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001886 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001887 if (i < 0)
1888 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001889 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001890}
1891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001892
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001893PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001894"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001896
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001898"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001899Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001900
Barry Warsaw53699e91996-12-10 23:23:01 +00001901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001902posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001903{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001904#ifdef MS_WINDOWS
1905 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1906#else
1907 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1908#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001909}
1910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001911
Guido van Rossumb6775db1994-08-01 11:34:53 +00001912#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001914"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001915Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001916
Barry Warsaw53699e91996-12-10 23:23:01 +00001917static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001918posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001919{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001920 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001921 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001922
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001924 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001925 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001926 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001927 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001928 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001929 u.sysname,
1930 u.nodename,
1931 u.release,
1932 u.version,
1933 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001934}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001935#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001936
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001937static int
1938extract_time(PyObject *t, long* sec, long* usec)
1939{
1940 long intval;
1941 if (PyFloat_Check(t)) {
1942 double tval = PyFloat_AsDouble(t);
1943 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1944 if (!intobj)
1945 return -1;
1946 intval = PyInt_AsLong(intobj);
1947 Py_DECREF(intobj);
1948 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001949 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001950 if (*usec < 0)
1951 /* If rounding gave us a negative number,
1952 truncate. */
1953 *usec = 0;
1954 return 0;
1955 }
1956 intval = PyInt_AsLong(t);
1957 if (intval == -1 && PyErr_Occurred())
1958 return -1;
1959 *sec = intval;
1960 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001961 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001962}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001965"utime(path, (atime, utime))\n\
1966utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001967Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001968second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Barry Warsaw53699e91996-12-10 23:23:01 +00001970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001971posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001972{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001973 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001974 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001975 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001976 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001977
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001978#if defined(HAVE_UTIMES)
1979 struct timeval buf[2];
1980#define ATIME buf[0].tv_sec
1981#define MTIME buf[1].tv_sec
1982#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001983/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001984 struct utimbuf buf;
1985#define ATIME buf.actime
1986#define MTIME buf.modtime
1987#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001988#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001989 time_t buf[2];
1990#define ATIME buf[0]
1991#define MTIME buf[1]
1992#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001993#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001994
Barry Warsaw3cef8562000-05-01 16:17:24 +00001995 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001996 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001997 if (arg == Py_None) {
1998 /* optional time values not given */
1999 Py_BEGIN_ALLOW_THREADS
2000 res = utime(path, NULL);
2001 Py_END_ALLOW_THREADS
2002 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002003 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002004 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002005 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002006 return NULL;
2007 }
2008 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002009 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2010 &atime, &ausec) == -1)
2011 return NULL;
2012 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2013 &mtime, &musec) == -1)
2014 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002015 ATIME = atime;
2016 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002017#ifdef HAVE_UTIMES
2018 buf[0].tv_usec = ausec;
2019 buf[1].tv_usec = musec;
2020 Py_BEGIN_ALLOW_THREADS
2021 res = utimes(path, buf);
2022 Py_END_ALLOW_THREADS
2023#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002024 Py_BEGIN_ALLOW_THREADS
2025 res = utime(path, UTIME_ARG);
2026 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002027#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002028 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002029 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002030 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002031 Py_INCREF(Py_None);
2032 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002033#undef UTIME_ARG
2034#undef ATIME
2035#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002036}
2037
Guido van Rossum85e3b011991-06-03 12:42:10 +00002038
Guido van Rossum3b066191991-06-04 19:40:25 +00002039/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
Barry Warsaw53699e91996-12-10 23:23:01 +00002045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002046posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002047{
2048 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002049 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002050 return NULL;
2051 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002052 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002053}
2054
Martin v. Löwis114619e2002-10-07 06:44:21 +00002055#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2056static void
2057free_string_array(char **array, int count)
2058{
2059 int i;
2060 for (i = 0; i < count; i++)
2061 PyMem_Free(array[i]);
2062 PyMem_DEL(array);
2063}
2064#endif
2065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002067#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002068PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002069"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070Execute an executable path with arguments, replacing current process.\n\
2071\n\
2072 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Barry Warsaw53699e91996-12-10 23:23:01 +00002075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002076posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002077{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002078 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002080 char **argvlist;
2081 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083
Guido van Rossum89b33251993-10-22 14:26:06 +00002084 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002085 argv is a list or tuple of strings. */
2086
Martin v. Löwis114619e2002-10-07 06:44:21 +00002087 if (!PyArg_ParseTuple(args, "etO:execv",
2088 Py_FileSystemDefaultEncoding,
2089 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002090 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002091 if (PyList_Check(argv)) {
2092 argc = PyList_Size(argv);
2093 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002094 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002095 else if (PyTuple_Check(argv)) {
2096 argc = PyTuple_Size(argv);
2097 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002098 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002099 else {
Fred Drake661ea262000-10-24 19:57:45 +00002100 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002101 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002102 return NULL;
2103 }
2104
2105 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002106 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002107 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002108 return NULL;
2109 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002110
Barry Warsaw53699e91996-12-10 23:23:01 +00002111 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002112 if (argvlist == NULL) {
2113 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002114 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002115 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002116 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002117 if (!PyArg_Parse((*getitem)(argv, i), "et",
2118 Py_FileSystemDefaultEncoding,
2119 &argvlist[i])) {
2120 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002121 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002122 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002123 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002124 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002125
Guido van Rossum85e3b011991-06-03 12:42:10 +00002126 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002127 }
2128 argvlist[argc] = NULL;
2129
Guido van Rossumb6775db1994-08-01 11:34:53 +00002130#ifdef BAD_EXEC_PROTOTYPES
2131 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002133 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002134#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002135
Guido van Rossum85e3b011991-06-03 12:42:10 +00002136 /* If we get here it's definitely an error */
2137
Martin v. Löwis114619e2002-10-07 06:44:21 +00002138 free_string_array(argvlist, argc);
2139 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002140 return posix_error();
2141}
2142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002143
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002144PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002145"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002146Execute a path with arguments and environment, replacing current process.\n\
2147\n\
2148 path: path of executable file\n\
2149 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002150 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002151
Barry Warsaw53699e91996-12-10 23:23:01 +00002152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002153posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002154{
2155 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002156 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002157 char **argvlist;
2158 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002159 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002160 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002161 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002162 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002163
2164 /* execve has three arguments: (path, argv, env), where
2165 argv is a list or tuple of strings and env is a dictionary
2166 like posix.environ. */
2167
Martin v. Löwis114619e2002-10-07 06:44:21 +00002168 if (!PyArg_ParseTuple(args, "etOO:execve",
2169 Py_FileSystemDefaultEncoding,
2170 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002171 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002172 if (PyList_Check(argv)) {
2173 argc = PyList_Size(argv);
2174 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002175 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002176 else if (PyTuple_Check(argv)) {
2177 argc = PyTuple_Size(argv);
2178 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002179 }
2180 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002181 PyErr_SetString(PyExc_TypeError,
2182 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002183 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002184 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002185 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002186 PyErr_SetString(PyExc_TypeError,
2187 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002188 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002189 }
2190
Guido van Rossum50422b42000-04-26 20:34:28 +00002191 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002192 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002193 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002194 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002195 }
2196
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002198 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002199 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002200 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002201 }
2202 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002203 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002204 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002205 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002206 &argvlist[i]))
2207 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002208 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002209 goto fail_1;
2210 }
2211 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002212 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002213 argvlist[argc] = NULL;
2214
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002215 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002216 if (i < 0)
2217 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002218 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002219 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002220 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002221 goto fail_1;
2222 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002223 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002224 keys = PyMapping_Keys(env);
2225 vals = PyMapping_Values(env);
2226 if (!keys || !vals)
2227 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002228 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2229 PyErr_SetString(PyExc_TypeError,
2230 "execve(): env.keys() or env.values() is not a list");
2231 goto fail_2;
2232 }
Tim Peters5aa91602002-01-30 05:46:57 +00002233
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002234 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002235 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002236 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002237
2238 key = PyList_GetItem(keys, pos);
2239 val = PyList_GetItem(vals, pos);
2240 if (!key || !val)
2241 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002242
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002243 if (!PyArg_Parse(
2244 key,
2245 "s;execve() arg 3 contains a non-string key",
2246 &k) ||
2247 !PyArg_Parse(
2248 val,
2249 "s;execve() arg 3 contains a non-string value",
2250 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002251 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002252 goto fail_2;
2253 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002254
2255#if defined(PYOS_OS2)
2256 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2257 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2258#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002259 len = PyString_Size(key) + PyString_Size(val) + 2;
2260 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002262 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002263 goto fail_2;
2264 }
Tim Petersc8996f52001-12-03 20:41:00 +00002265 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002266 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002267#if defined(PYOS_OS2)
2268 }
2269#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002270 }
2271 envlist[envc] = 0;
2272
Guido van Rossumb6775db1994-08-01 11:34:53 +00002273
2274#ifdef BAD_EXEC_PROTOTYPES
2275 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002276#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002277 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002278#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002279
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002280 /* If we get here it's definitely an error */
2281
2282 (void) posix_error();
2283
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002284 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002285 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002286 PyMem_DEL(envlist[envc]);
2287 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002288 fail_1:
2289 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002290 Py_XDECREF(vals);
2291 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002292 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002293 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002294 return NULL;
2295}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002296#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002298
Guido van Rossuma1065681999-01-25 23:20:23 +00002299#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002301"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002302Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002303\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002304 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002305 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002306 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002307
2308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002309posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002310{
2311 char *path;
2312 PyObject *argv;
2313 char **argvlist;
2314 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002315 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002316 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002317
2318 /* spawnv has three arguments: (mode, path, argv), where
2319 argv is a list or tuple of strings. */
2320
Martin v. Löwis114619e2002-10-07 06:44:21 +00002321 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2322 Py_FileSystemDefaultEncoding,
2323 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002324 return NULL;
2325 if (PyList_Check(argv)) {
2326 argc = PyList_Size(argv);
2327 getitem = PyList_GetItem;
2328 }
2329 else if (PyTuple_Check(argv)) {
2330 argc = PyTuple_Size(argv);
2331 getitem = PyTuple_GetItem;
2332 }
2333 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002334 PyErr_SetString(PyExc_TypeError,
2335 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002336 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002337 return NULL;
2338 }
2339
2340 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002341 if (argvlist == NULL) {
2342 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002343 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002345 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002346 if (!PyArg_Parse((*getitem)(argv, i), "et",
2347 Py_FileSystemDefaultEncoding,
2348 &argvlist[i])) {
2349 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002350 PyErr_SetString(
2351 PyExc_TypeError,
2352 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002353 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002354 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002355 }
2356 }
2357 argvlist[argc] = NULL;
2358
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002359#if defined(PYOS_OS2) && defined(PYCC_GCC)
2360 Py_BEGIN_ALLOW_THREADS
2361 spawnval = spawnv(mode, path, argvlist);
2362 Py_END_ALLOW_THREADS
2363#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002364 if (mode == _OLD_P_OVERLAY)
2365 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002366
Tim Peters25059d32001-12-07 20:35:43 +00002367 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002368 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002369 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002370#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002371
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 free_string_array(argvlist, argc);
2373 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002374
Fred Drake699f3522000-06-29 21:12:41 +00002375 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002376 return posix_error();
2377 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002378#if SIZEOF_LONG == SIZEOF_VOID_P
2379 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002380#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002381 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002382#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002383}
2384
2385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002386PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002387"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002388Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002389\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002390 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002391 path: path of executable file\n\
2392 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002393 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002394
2395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002396posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002397{
2398 char *path;
2399 PyObject *argv, *env;
2400 char **argvlist;
2401 char **envlist;
2402 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2403 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002404 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002405 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002406 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002407
2408 /* spawnve has four arguments: (mode, path, argv, env), where
2409 argv is a list or tuple of strings and env is a dictionary
2410 like posix.environ. */
2411
Martin v. Löwis114619e2002-10-07 06:44:21 +00002412 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2413 Py_FileSystemDefaultEncoding,
2414 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002415 return NULL;
2416 if (PyList_Check(argv)) {
2417 argc = PyList_Size(argv);
2418 getitem = PyList_GetItem;
2419 }
2420 else if (PyTuple_Check(argv)) {
2421 argc = PyTuple_Size(argv);
2422 getitem = PyTuple_GetItem;
2423 }
2424 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002425 PyErr_SetString(PyExc_TypeError,
2426 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002427 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002428 }
2429 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002430 PyErr_SetString(PyExc_TypeError,
2431 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002432 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002433 }
2434
2435 argvlist = PyMem_NEW(char *, argc+1);
2436 if (argvlist == NULL) {
2437 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002438 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002439 }
2440 for (i = 0; i < argc; i++) {
2441 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002442 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002443 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002444 &argvlist[i]))
2445 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002446 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002447 goto fail_1;
2448 }
2449 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002450 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002451 argvlist[argc] = NULL;
2452
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002453 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002454 if (i < 0)
2455 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002456 envlist = PyMem_NEW(char *, i + 1);
2457 if (envlist == NULL) {
2458 PyErr_NoMemory();
2459 goto fail_1;
2460 }
2461 envc = 0;
2462 keys = PyMapping_Keys(env);
2463 vals = PyMapping_Values(env);
2464 if (!keys || !vals)
2465 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002466 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2467 PyErr_SetString(PyExc_TypeError,
2468 "spawnve(): env.keys() or env.values() is not a list");
2469 goto fail_2;
2470 }
Tim Peters5aa91602002-01-30 05:46:57 +00002471
Guido van Rossuma1065681999-01-25 23:20:23 +00002472 for (pos = 0; pos < i; pos++) {
2473 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002474 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002475
2476 key = PyList_GetItem(keys, pos);
2477 val = PyList_GetItem(vals, pos);
2478 if (!key || !val)
2479 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002480
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002481 if (!PyArg_Parse(
2482 key,
2483 "s;spawnve() arg 3 contains a non-string key",
2484 &k) ||
2485 !PyArg_Parse(
2486 val,
2487 "s;spawnve() arg 3 contains a non-string value",
2488 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002489 {
2490 goto fail_2;
2491 }
Tim Petersc8996f52001-12-03 20:41:00 +00002492 len = PyString_Size(key) + PyString_Size(val) + 2;
2493 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002494 if (p == NULL) {
2495 PyErr_NoMemory();
2496 goto fail_2;
2497 }
Tim Petersc8996f52001-12-03 20:41:00 +00002498 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002499 envlist[envc++] = p;
2500 }
2501 envlist[envc] = 0;
2502
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002503#if defined(PYOS_OS2) && defined(PYCC_GCC)
2504 Py_BEGIN_ALLOW_THREADS
2505 spawnval = spawnve(mode, path, argvlist, envlist);
2506 Py_END_ALLOW_THREADS
2507#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002508 if (mode == _OLD_P_OVERLAY)
2509 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002510
2511 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002512 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002513 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002514#endif
Tim Peters25059d32001-12-07 20:35:43 +00002515
Fred Drake699f3522000-06-29 21:12:41 +00002516 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002517 (void) posix_error();
2518 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002519#if SIZEOF_LONG == SIZEOF_VOID_P
2520 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002521#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002522 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002523#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002524
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002525 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002526 while (--envc >= 0)
2527 PyMem_DEL(envlist[envc]);
2528 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002529 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002530 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002531 Py_XDECREF(vals);
2532 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002533 fail_0:
2534 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002535 return res;
2536}
2537#endif /* HAVE_SPAWNV */
2538
2539
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002540#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002541PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002542"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002543Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2544\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002545Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002546
2547static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002548posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002549{
Neal Norwitze241ce82003-02-17 18:17:05 +00002550 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002551 if (pid == -1)
2552 return posix_error();
2553 PyOS_AfterFork();
2554 return PyInt_FromLong((long)pid);
2555}
2556#endif
2557
2558
Guido van Rossumad0ee831995-03-01 10:34:45 +00002559#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002560PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002561"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002562Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002563Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002564
Barry Warsaw53699e91996-12-10 23:23:01 +00002565static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002566posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002567{
Neal Norwitze241ce82003-02-17 18:17:05 +00002568 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002569 if (pid == -1)
2570 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002571 if (pid == 0)
2572 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002573 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002574}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002575#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002576
Neal Norwitzb59798b2003-03-21 01:43:31 +00002577/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002578/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2579#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002580#define DEV_PTY_FILE "/dev/ptc"
2581#define HAVE_DEV_PTMX
2582#else
2583#define DEV_PTY_FILE "/dev/ptmx"
2584#endif
2585
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002586#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002587#ifdef HAVE_PTY_H
2588#include <pty.h>
2589#else
2590#ifdef HAVE_LIBUTIL_H
2591#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002592#endif /* HAVE_LIBUTIL_H */
2593#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002594#ifdef HAVE_STROPTS_H
2595#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002596#endif
2597#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002598
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002599#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002600PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002601"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002603
2604static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002605posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002606{
2607 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002608#ifndef HAVE_OPENPTY
2609 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002610#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002611#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002612 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002613#ifdef sun
2614 extern char *ptsname();
2615#endif
2616#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002617
Thomas Wouters70c21a12000-07-14 14:28:33 +00002618#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002619 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2620 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002621#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002622 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2623 if (slave_name == NULL)
2624 return posix_error();
2625
2626 slave_fd = open(slave_name, O_RDWR);
2627 if (slave_fd < 0)
2628 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002629#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002630 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002631 if (master_fd < 0)
2632 return posix_error();
2633 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002634 /* change permission of slave */
2635 if (grantpt(master_fd) < 0) {
2636 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002637 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002638 }
2639 /* unlock slave */
2640 if (unlockpt(master_fd) < 0) {
2641 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002642 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002643 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002644 signal(SIGCHLD, sig_saved);
2645 slave_name = ptsname(master_fd); /* get name of slave */
2646 if (slave_name == NULL)
2647 return posix_error();
2648 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2649 if (slave_fd < 0)
2650 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002651#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002652 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2653 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002654#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002655 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002656#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002657#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002658#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002659
Fred Drake8cef4cf2000-06-28 16:40:38 +00002660 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002661
Fred Drake8cef4cf2000-06-28 16:40:38 +00002662}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002663#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002664
2665#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002666PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002667"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002668Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2669Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002670To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002671
2672static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002673posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002674{
2675 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002676
Fred Drake8cef4cf2000-06-28 16:40:38 +00002677 pid = forkpty(&master_fd, NULL, NULL, NULL);
2678 if (pid == -1)
2679 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002680 if (pid == 0)
2681 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002682 return Py_BuildValue("(ii)", pid, master_fd);
2683}
2684#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Guido van Rossumad0ee831995-03-01 10:34:45 +00002686#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002687PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002688"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002689Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002690
Barry Warsaw53699e91996-12-10 23:23:01 +00002691static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002692posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002693{
Barry Warsaw53699e91996-12-10 23:23:01 +00002694 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002695}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002696#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002698
Guido van Rossumad0ee831995-03-01 10:34:45 +00002699#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002701"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002703
Barry Warsaw53699e91996-12-10 23:23:01 +00002704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002705posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002706{
Barry Warsaw53699e91996-12-10 23:23:01 +00002707 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002708}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002709#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002711
Guido van Rossumad0ee831995-03-01 10:34:45 +00002712#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002713PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002714"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002715Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002716
Barry Warsaw53699e91996-12-10 23:23:01 +00002717static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002718posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002719{
Barry Warsaw53699e91996-12-10 23:23:01 +00002720 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002721}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002722#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002726"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002727Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Barry Warsaw53699e91996-12-10 23:23:01 +00002729static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002730posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002731{
Barry Warsaw53699e91996-12-10 23:23:01 +00002732 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002733}
2734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002735
Fred Drakec9680921999-12-13 16:37:25 +00002736#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002737PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002738"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002739Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002740
2741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002742posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002743{
2744 PyObject *result = NULL;
2745
Fred Drakec9680921999-12-13 16:37:25 +00002746#ifdef NGROUPS_MAX
2747#define MAX_GROUPS NGROUPS_MAX
2748#else
2749 /* defined to be 16 on Solaris7, so this should be a small number */
2750#define MAX_GROUPS 64
2751#endif
2752 gid_t grouplist[MAX_GROUPS];
2753 int n;
2754
2755 n = getgroups(MAX_GROUPS, grouplist);
2756 if (n < 0)
2757 posix_error();
2758 else {
2759 result = PyList_New(n);
2760 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002761 int i;
2762 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002763 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002764 if (o == NULL) {
2765 Py_DECREF(result);
2766 result = NULL;
2767 break;
2768 }
2769 PyList_SET_ITEM(result, i, o);
2770 }
2771 }
2772 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002773
Fred Drakec9680921999-12-13 16:37:25 +00002774 return result;
2775}
2776#endif
2777
Martin v. Löwis606edc12002-06-13 21:09:11 +00002778#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002779PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002780"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002781Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002782
2783static PyObject *
2784posix_getpgid(PyObject *self, PyObject *args)
2785{
2786 int pid, pgid;
2787 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2788 return NULL;
2789 pgid = getpgid(pid);
2790 if (pgid < 0)
2791 return posix_error();
2792 return PyInt_FromLong((long)pgid);
2793}
2794#endif /* HAVE_GETPGID */
2795
2796
Guido van Rossumb6775db1994-08-01 11:34:53 +00002797#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002798PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002799"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002800Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002801
Barry Warsaw53699e91996-12-10 23:23:01 +00002802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002803posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002804{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002805#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002806 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002807#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002808 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002809#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002810}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002811#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002813
Guido van Rossumb6775db1994-08-01 11:34:53 +00002814#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002816"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002817Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002818
Barry Warsaw53699e91996-12-10 23:23:01 +00002819static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002820posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002821{
Guido van Rossum64933891994-10-20 21:56:42 +00002822#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002823 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002824#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002825 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002826#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002827 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002828 Py_INCREF(Py_None);
2829 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002830}
2831
Guido van Rossumb6775db1994-08-01 11:34:53 +00002832#endif /* HAVE_SETPGRP */
2833
Guido van Rossumad0ee831995-03-01 10:34:45 +00002834#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002835PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002836"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838
Barry Warsaw53699e91996-12-10 23:23:01 +00002839static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002840posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002841{
Barry Warsaw53699e91996-12-10 23:23:01 +00002842 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002843}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002844#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002846
Fred Drake12c6e2d1999-12-14 21:25:03 +00002847#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002849"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002850Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002851
2852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002853posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002854{
Neal Norwitze241ce82003-02-17 18:17:05 +00002855 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002856 char *name;
2857 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002858
Fred Drakea30680b2000-12-06 21:24:28 +00002859 errno = 0;
2860 name = getlogin();
2861 if (name == NULL) {
2862 if (errno)
2863 posix_error();
2864 else
2865 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002866 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002867 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002868 else
2869 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002870 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002871
Fred Drake12c6e2d1999-12-14 21:25:03 +00002872 return result;
2873}
2874#endif
2875
Guido van Rossumad0ee831995-03-01 10:34:45 +00002876#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002878"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002880
Barry Warsaw53699e91996-12-10 23:23:01 +00002881static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002882posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002883{
Barry Warsaw53699e91996-12-10 23:23:01 +00002884 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002885}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002886#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002888
Guido van Rossumad0ee831995-03-01 10:34:45 +00002889#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002890PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002891"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002892Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002893
Barry Warsaw53699e91996-12-10 23:23:01 +00002894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002895posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002896{
2897 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002898 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002899 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002900#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002901 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2902 APIRET rc;
2903 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002904 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002905
2906 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2907 APIRET rc;
2908 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002909 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002910
2911 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002912 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002913#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002914 if (kill(pid, sig) == -1)
2915 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002916#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002917 Py_INCREF(Py_None);
2918 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002919}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002920#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002921
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002922#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002923PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002924"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002925Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002926
2927static PyObject *
2928posix_killpg(PyObject *self, PyObject *args)
2929{
2930 int pgid, sig;
2931 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2932 return NULL;
2933 if (killpg(pgid, sig) == -1)
2934 return posix_error();
2935 Py_INCREF(Py_None);
2936 return Py_None;
2937}
2938#endif
2939
Guido van Rossumc0125471996-06-28 18:55:32 +00002940#ifdef HAVE_PLOCK
2941
2942#ifdef HAVE_SYS_LOCK_H
2943#include <sys/lock.h>
2944#endif
2945
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002946PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002947"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002948Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Barry Warsaw53699e91996-12-10 23:23:01 +00002950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002951posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002952{
2953 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002954 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002955 return NULL;
2956 if (plock(op) == -1)
2957 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002958 Py_INCREF(Py_None);
2959 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002960}
2961#endif
2962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002963
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002964#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002966"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002967Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002968
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002969#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002970#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002971static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002972async_system(const char *command)
2973{
2974 char *p, errormsg[256], args[1024];
2975 RESULTCODES rcodes;
2976 APIRET rc;
2977 char *shell = getenv("COMSPEC");
2978 if (!shell)
2979 shell = "cmd";
2980
2981 strcpy(args, shell);
2982 p = &args[ strlen(args)+1 ];
2983 strcpy(p, "/c ");
2984 strcat(p, command);
2985 p += strlen(p) + 1;
2986 *p = '\0';
2987
2988 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002989 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002990 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002991 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002992 &rcodes, shell);
2993 return rc;
2994}
2995
Guido van Rossumd48f2521997-12-05 22:19:34 +00002996static FILE *
2997popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002998{
2999 HFILE rhan, whan;
3000 FILE *retfd = NULL;
3001 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3002
Guido van Rossumd48f2521997-12-05 22:19:34 +00003003 if (rc != NO_ERROR) {
3004 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003005 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003006 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003007
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003008 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3009 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003010
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003011 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3012 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003013
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003014 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3015 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003016
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003017 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003018 }
3019
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003020 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3021 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003022
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003023 if (rc == NO_ERROR)
3024 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3025
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003026 close(oldfd); /* And Close Saved STDOUT Handle */
3027 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003028
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003029 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3030 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003031
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003032 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3033 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003034
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003035 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3036 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003037
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003038 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003039 }
3040
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003041 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3042 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003043
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003044 if (rc == NO_ERROR)
3045 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3046
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003047 close(oldfd); /* And Close Saved STDIN Handle */
3048 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003049
Guido van Rossumd48f2521997-12-05 22:19:34 +00003050 } else {
3051 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003052 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003053 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003054}
3055
3056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003057posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003058{
3059 char *name;
3060 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003061 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003062 FILE *fp;
3063 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003064 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003065 return NULL;
3066 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003067 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003068 Py_END_ALLOW_THREADS
3069 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003070 return os2_error(err);
3071
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003072 f = PyFile_FromFile(fp, name, mode, fclose);
3073 if (f != NULL)
3074 PyFile_SetBufSize(f, bufsize);
3075 return f;
3076}
3077
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003078#elif defined(PYCC_GCC)
3079
3080/* standard posix version of popen() support */
3081static PyObject *
3082posix_popen(PyObject *self, PyObject *args)
3083{
3084 char *name;
3085 char *mode = "r";
3086 int bufsize = -1;
3087 FILE *fp;
3088 PyObject *f;
3089 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3090 return NULL;
3091 Py_BEGIN_ALLOW_THREADS
3092 fp = popen(name, mode);
3093 Py_END_ALLOW_THREADS
3094 if (fp == NULL)
3095 return posix_error();
3096 f = PyFile_FromFile(fp, name, mode, pclose);
3097 if (f != NULL)
3098 PyFile_SetBufSize(f, bufsize);
3099 return f;
3100}
3101
3102/* fork() under OS/2 has lots'o'warts
3103 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3104 * most of this code is a ripoff of the win32 code, but using the
3105 * capabilities of EMX's C library routines
3106 */
3107
3108/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3109#define POPEN_1 1
3110#define POPEN_2 2
3111#define POPEN_3 3
3112#define POPEN_4 4
3113
3114static PyObject *_PyPopen(char *, int, int, int);
3115static int _PyPclose(FILE *file);
3116
3117/*
3118 * Internal dictionary mapping popen* file pointers to process handles,
3119 * for use when retrieving the process exit code. See _PyPclose() below
3120 * for more information on this dictionary's use.
3121 */
3122static PyObject *_PyPopenProcs = NULL;
3123
3124/* os2emx version of popen2()
3125 *
3126 * The result of this function is a pipe (file) connected to the
3127 * process's stdin, and a pipe connected to the process's stdout.
3128 */
3129
3130static PyObject *
3131os2emx_popen2(PyObject *self, PyObject *args)
3132{
3133 PyObject *f;
3134 int tm=0;
3135
3136 char *cmdstring;
3137 char *mode = "t";
3138 int bufsize = -1;
3139 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3140 return NULL;
3141
3142 if (*mode == 't')
3143 tm = O_TEXT;
3144 else if (*mode != 'b') {
3145 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3146 return NULL;
3147 } else
3148 tm = O_BINARY;
3149
3150 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3151
3152 return f;
3153}
3154
3155/*
3156 * Variation on os2emx.popen2
3157 *
3158 * The result of this function is 3 pipes - the process's stdin,
3159 * stdout and stderr
3160 */
3161
3162static PyObject *
3163os2emx_popen3(PyObject *self, PyObject *args)
3164{
3165 PyObject *f;
3166 int tm = 0;
3167
3168 char *cmdstring;
3169 char *mode = "t";
3170 int bufsize = -1;
3171 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3172 return NULL;
3173
3174 if (*mode == 't')
3175 tm = O_TEXT;
3176 else if (*mode != 'b') {
3177 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3178 return NULL;
3179 } else
3180 tm = O_BINARY;
3181
3182 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3183
3184 return f;
3185}
3186
3187/*
3188 * Variation on os2emx.popen2
3189 *
Tim Peters11b23062003-04-23 02:39:17 +00003190 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003191 * and stdout+stderr combined as a single pipe.
3192 */
3193
3194static PyObject *
3195os2emx_popen4(PyObject *self, PyObject *args)
3196{
3197 PyObject *f;
3198 int tm = 0;
3199
3200 char *cmdstring;
3201 char *mode = "t";
3202 int bufsize = -1;
3203 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3204 return NULL;
3205
3206 if (*mode == 't')
3207 tm = O_TEXT;
3208 else if (*mode != 'b') {
3209 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3210 return NULL;
3211 } else
3212 tm = O_BINARY;
3213
3214 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3215
3216 return f;
3217}
3218
3219/* a couple of structures for convenient handling of multiple
3220 * file handles and pipes
3221 */
3222struct file_ref
3223{
3224 int handle;
3225 int flags;
3226};
3227
3228struct pipe_ref
3229{
3230 int rd;
3231 int wr;
3232};
3233
3234/* The following code is derived from the win32 code */
3235
3236static PyObject *
3237_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3238{
3239 struct file_ref stdio[3];
3240 struct pipe_ref p_fd[3];
3241 FILE *p_s[3];
3242 int file_count, i, pipe_err, pipe_pid;
3243 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3244 PyObject *f, *p_f[3];
3245
3246 /* file modes for subsequent fdopen's on pipe handles */
3247 if (mode == O_TEXT)
3248 {
3249 rd_mode = "rt";
3250 wr_mode = "wt";
3251 }
3252 else
3253 {
3254 rd_mode = "rb";
3255 wr_mode = "wb";
3256 }
3257
3258 /* prepare shell references */
3259 if ((shell = getenv("EMXSHELL")) == NULL)
3260 if ((shell = getenv("COMSPEC")) == NULL)
3261 {
3262 errno = ENOENT;
3263 return posix_error();
3264 }
3265
3266 sh_name = _getname(shell);
3267 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3268 opt = "/c";
3269 else
3270 opt = "-c";
3271
3272 /* save current stdio fds + their flags, and set not inheritable */
3273 i = pipe_err = 0;
3274 while (pipe_err >= 0 && i < 3)
3275 {
3276 pipe_err = stdio[i].handle = dup(i);
3277 stdio[i].flags = fcntl(i, F_GETFD, 0);
3278 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3279 i++;
3280 }
3281 if (pipe_err < 0)
3282 {
3283 /* didn't get them all saved - clean up and bail out */
3284 int saved_err = errno;
3285 while (i-- > 0)
3286 {
3287 close(stdio[i].handle);
3288 }
3289 errno = saved_err;
3290 return posix_error();
3291 }
3292
3293 /* create pipe ends */
3294 file_count = 2;
3295 if (n == POPEN_3)
3296 file_count = 3;
3297 i = pipe_err = 0;
3298 while ((pipe_err == 0) && (i < file_count))
3299 pipe_err = pipe((int *)&p_fd[i++]);
3300 if (pipe_err < 0)
3301 {
3302 /* didn't get them all made - clean up and bail out */
3303 while (i-- > 0)
3304 {
3305 close(p_fd[i].wr);
3306 close(p_fd[i].rd);
3307 }
3308 errno = EPIPE;
3309 return posix_error();
3310 }
3311
3312 /* change the actual standard IO streams over temporarily,
3313 * making the retained pipe ends non-inheritable
3314 */
3315 pipe_err = 0;
3316
3317 /* - stdin */
3318 if (dup2(p_fd[0].rd, 0) == 0)
3319 {
3320 close(p_fd[0].rd);
3321 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3322 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3323 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3324 {
3325 close(p_fd[0].wr);
3326 pipe_err = -1;
3327 }
3328 }
3329 else
3330 {
3331 pipe_err = -1;
3332 }
3333
3334 /* - stdout */
3335 if (pipe_err == 0)
3336 {
3337 if (dup2(p_fd[1].wr, 1) == 1)
3338 {
3339 close(p_fd[1].wr);
3340 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3341 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3342 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3343 {
3344 close(p_fd[1].rd);
3345 pipe_err = -1;
3346 }
3347 }
3348 else
3349 {
3350 pipe_err = -1;
3351 }
3352 }
3353
3354 /* - stderr, as required */
3355 if (pipe_err == 0)
3356 switch (n)
3357 {
3358 case POPEN_3:
3359 {
3360 if (dup2(p_fd[2].wr, 2) == 2)
3361 {
3362 close(p_fd[2].wr);
3363 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3364 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3365 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3366 {
3367 close(p_fd[2].rd);
3368 pipe_err = -1;
3369 }
3370 }
3371 else
3372 {
3373 pipe_err = -1;
3374 }
3375 break;
3376 }
3377
3378 case POPEN_4:
3379 {
3380 if (dup2(1, 2) != 2)
3381 {
3382 pipe_err = -1;
3383 }
3384 break;
3385 }
3386 }
3387
3388 /* spawn the child process */
3389 if (pipe_err == 0)
3390 {
3391 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3392 if (pipe_pid == -1)
3393 {
3394 pipe_err = -1;
3395 }
3396 else
3397 {
3398 /* save the PID into the FILE structure
3399 * NOTE: this implementation doesn't actually
3400 * take advantage of this, but do it for
3401 * completeness - AIM Apr01
3402 */
3403 for (i = 0; i < file_count; i++)
3404 p_s[i]->_pid = pipe_pid;
3405 }
3406 }
3407
3408 /* reset standard IO to normal */
3409 for (i = 0; i < 3; i++)
3410 {
3411 dup2(stdio[i].handle, i);
3412 fcntl(i, F_SETFD, stdio[i].flags);
3413 close(stdio[i].handle);
3414 }
3415
3416 /* if any remnant problems, clean up and bail out */
3417 if (pipe_err < 0)
3418 {
3419 for (i = 0; i < 3; i++)
3420 {
3421 close(p_fd[i].rd);
3422 close(p_fd[i].wr);
3423 }
3424 errno = EPIPE;
3425 return posix_error_with_filename(cmdstring);
3426 }
3427
3428 /* build tuple of file objects to return */
3429 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3430 PyFile_SetBufSize(p_f[0], bufsize);
3431 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3432 PyFile_SetBufSize(p_f[1], bufsize);
3433 if (n == POPEN_3)
3434 {
3435 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3436 PyFile_SetBufSize(p_f[0], bufsize);
3437 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3438 }
3439 else
3440 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3441
3442 /*
3443 * Insert the files we've created into the process dictionary
3444 * all referencing the list with the process handle and the
3445 * initial number of files (see description below in _PyPclose).
3446 * Since if _PyPclose later tried to wait on a process when all
3447 * handles weren't closed, it could create a deadlock with the
3448 * child, we spend some energy here to try to ensure that we
3449 * either insert all file handles into the dictionary or none
3450 * at all. It's a little clumsy with the various popen modes
3451 * and variable number of files involved.
3452 */
3453 if (!_PyPopenProcs)
3454 {
3455 _PyPopenProcs = PyDict_New();
3456 }
3457
3458 if (_PyPopenProcs)
3459 {
3460 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3461 int ins_rc[3];
3462
3463 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3464 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3465
3466 procObj = PyList_New(2);
3467 pidObj = PyInt_FromLong((long) pipe_pid);
3468 intObj = PyInt_FromLong((long) file_count);
3469
3470 if (procObj && pidObj && intObj)
3471 {
3472 PyList_SetItem(procObj, 0, pidObj);
3473 PyList_SetItem(procObj, 1, intObj);
3474
3475 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3476 if (fileObj[0])
3477 {
3478 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3479 fileObj[0],
3480 procObj);
3481 }
3482 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3483 if (fileObj[1])
3484 {
3485 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3486 fileObj[1],
3487 procObj);
3488 }
3489 if (file_count >= 3)
3490 {
3491 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3492 if (fileObj[2])
3493 {
3494 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3495 fileObj[2],
3496 procObj);
3497 }
3498 }
3499
3500 if (ins_rc[0] < 0 || !fileObj[0] ||
3501 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3502 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3503 {
3504 /* Something failed - remove any dictionary
3505 * entries that did make it.
3506 */
3507 if (!ins_rc[0] && fileObj[0])
3508 {
3509 PyDict_DelItem(_PyPopenProcs,
3510 fileObj[0]);
3511 }
3512 if (!ins_rc[1] && fileObj[1])
3513 {
3514 PyDict_DelItem(_PyPopenProcs,
3515 fileObj[1]);
3516 }
3517 if (!ins_rc[2] && fileObj[2])
3518 {
3519 PyDict_DelItem(_PyPopenProcs,
3520 fileObj[2]);
3521 }
3522 }
3523 }
Tim Peters11b23062003-04-23 02:39:17 +00003524
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003525 /*
3526 * Clean up our localized references for the dictionary keys
3527 * and value since PyDict_SetItem will Py_INCREF any copies
3528 * that got placed in the dictionary.
3529 */
3530 Py_XDECREF(procObj);
3531 Py_XDECREF(fileObj[0]);
3532 Py_XDECREF(fileObj[1]);
3533 Py_XDECREF(fileObj[2]);
3534 }
3535
3536 /* Child is launched. */
3537 return f;
3538}
3539
3540/*
3541 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3542 * exit code for the child process and return as a result of the close.
3543 *
3544 * This function uses the _PyPopenProcs dictionary in order to map the
3545 * input file pointer to information about the process that was
3546 * originally created by the popen* call that created the file pointer.
3547 * The dictionary uses the file pointer as a key (with one entry
3548 * inserted for each file returned by the original popen* call) and a
3549 * single list object as the value for all files from a single call.
3550 * The list object contains the Win32 process handle at [0], and a file
3551 * count at [1], which is initialized to the total number of file
3552 * handles using that list.
3553 *
3554 * This function closes whichever handle it is passed, and decrements
3555 * the file count in the dictionary for the process handle pointed to
3556 * by this file. On the last close (when the file count reaches zero),
3557 * this function will wait for the child process and then return its
3558 * exit code as the result of the close() operation. This permits the
3559 * files to be closed in any order - it is always the close() of the
3560 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003561 *
3562 * NOTE: This function is currently called with the GIL released.
3563 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003564 */
3565
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003566static int _PyPclose(FILE *file)
3567{
3568 int result;
3569 int exit_code;
3570 int pipe_pid;
3571 PyObject *procObj, *pidObj, *intObj, *fileObj;
3572 int file_count;
3573#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003574 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003575#endif
3576
3577 /* Close the file handle first, to ensure it can't block the
3578 * child from exiting if it's the last handle.
3579 */
3580 result = fclose(file);
3581
3582#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003583 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003584#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003585 if (_PyPopenProcs)
3586 {
3587 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3588 (procObj = PyDict_GetItem(_PyPopenProcs,
3589 fileObj)) != NULL &&
3590 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3591 (intObj = PyList_GetItem(procObj,1)) != NULL)
3592 {
3593 pipe_pid = (int) PyInt_AsLong(pidObj);
3594 file_count = (int) PyInt_AsLong(intObj);
3595
3596 if (file_count > 1)
3597 {
3598 /* Still other files referencing process */
3599 file_count--;
3600 PyList_SetItem(procObj,1,
3601 PyInt_FromLong((long) file_count));
3602 }
3603 else
3604 {
3605 /* Last file for this process */
3606 if (result != EOF &&
3607 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3608 {
3609 /* extract exit status */
3610 if (WIFEXITED(exit_code))
3611 {
3612 result = WEXITSTATUS(exit_code);
3613 }
3614 else
3615 {
3616 errno = EPIPE;
3617 result = -1;
3618 }
3619 }
3620 else
3621 {
3622 /* Indicate failure - this will cause the file object
3623 * to raise an I/O error and translate the last
3624 * error code from errno. We do have a problem with
3625 * last errors that overlap the normal errno table,
3626 * but that's a consistent problem with the file object.
3627 */
3628 result = -1;
3629 }
3630 }
3631
3632 /* Remove this file pointer from dictionary */
3633 PyDict_DelItem(_PyPopenProcs, fileObj);
3634
3635 if (PyDict_Size(_PyPopenProcs) == 0)
3636 {
3637 Py_DECREF(_PyPopenProcs);
3638 _PyPopenProcs = NULL;
3639 }
3640
3641 } /* if object retrieval ok */
3642
3643 Py_XDECREF(fileObj);
3644 } /* if _PyPopenProcs */
3645
3646#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003647 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003648#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003649 return result;
3650}
3651
3652#endif /* PYCC_??? */
3653
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003654#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003655
3656/*
3657 * Portable 'popen' replacement for Win32.
3658 *
3659 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3660 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003661 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003662 */
3663
3664#include <malloc.h>
3665#include <io.h>
3666#include <fcntl.h>
3667
3668/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3669#define POPEN_1 1
3670#define POPEN_2 2
3671#define POPEN_3 3
3672#define POPEN_4 4
3673
3674static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003675static int _PyPclose(FILE *file);
3676
3677/*
3678 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003679 * for use when retrieving the process exit code. See _PyPclose() below
3680 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003681 */
3682static PyObject *_PyPopenProcs = NULL;
3683
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003684
3685/* popen that works from a GUI.
3686 *
3687 * The result of this function is a pipe (file) connected to the
3688 * processes stdin or stdout, depending on the requested mode.
3689 */
3690
3691static PyObject *
3692posix_popen(PyObject *self, PyObject *args)
3693{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003694 PyObject *f, *s;
3695 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003696
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003697 char *cmdstring;
3698 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003699 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003700 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003701 return NULL;
3702
3703 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003704
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 if (*mode == 'r')
3706 tm = _O_RDONLY;
3707 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003708 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003709 return NULL;
3710 } else
3711 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003712
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003713 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003714 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003715 return NULL;
3716 }
3717
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003718 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003719 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003720 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003721 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003722 else
3723 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3724
3725 return f;
3726}
3727
3728/* Variation on win32pipe.popen
3729 *
3730 * The result of this function is a pipe (file) connected to the
3731 * process's stdin, and a pipe connected to the process's stdout.
3732 */
3733
3734static PyObject *
3735win32_popen2(PyObject *self, PyObject *args)
3736{
3737 PyObject *f;
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 = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003742 int bufsize = -1;
3743 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003744 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003745
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003746 if (*mode == 't')
3747 tm = _O_TEXT;
3748 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003749 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003750 return NULL;
3751 } else
3752 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003753
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003754 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003755 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003756 return NULL;
3757 }
3758
3759 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003760
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003761 return f;
3762}
3763
3764/*
3765 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003766 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003767 * The result of this function is 3 pipes - the process's stdin,
3768 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003769 */
3770
3771static PyObject *
3772win32_popen3(PyObject *self, PyObject *args)
3773{
3774 PyObject *f;
3775 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003776
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003777 char *cmdstring;
3778 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003779 int bufsize = -1;
3780 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003781 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003782
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003783 if (*mode == 't')
3784 tm = _O_TEXT;
3785 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003786 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003787 return NULL;
3788 } else
3789 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003790
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003791 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003792 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003793 return NULL;
3794 }
3795
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003796 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003797
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003798 return f;
3799}
3800
3801/*
3802 * Variation on win32pipe.popen
3803 *
Tim Peters5aa91602002-01-30 05:46:57 +00003804 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003805 * and stdout+stderr combined as a single pipe.
3806 */
3807
3808static PyObject *
3809win32_popen4(PyObject *self, PyObject *args)
3810{
3811 PyObject *f;
3812 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003813
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003814 char *cmdstring;
3815 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003816 int bufsize = -1;
3817 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003818 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003819
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003820 if (*mode == 't')
3821 tm = _O_TEXT;
3822 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003823 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003824 return NULL;
3825 } else
3826 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003827
3828 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003829 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003830 return NULL;
3831 }
3832
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003833 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003834
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003835 return f;
3836}
3837
Mark Hammond08501372001-01-31 07:30:29 +00003838static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003839_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003840 HANDLE hStdin,
3841 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003842 HANDLE hStderr,
3843 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003844{
3845 PROCESS_INFORMATION piProcInfo;
3846 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003847 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003849 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003850 int i;
3851 int x;
3852
3853 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003854 char *comshell;
3855
Tim Peters92e4dd82002-10-05 01:47:34 +00003856 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003857 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3858 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003859
3860 /* Explicitly check if we are using COMMAND.COM. If we are
3861 * then use the w9xpopen hack.
3862 */
3863 comshell = s1 + x;
3864 while (comshell >= s1 && *comshell != '\\')
3865 --comshell;
3866 ++comshell;
3867
3868 if (GetVersion() < 0x80000000 &&
3869 _stricmp(comshell, "command.com") != 0) {
3870 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003871 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003872 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003873 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003874 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003875 }
3876 else {
3877 /*
Tim Peters402d5982001-08-27 06:37:48 +00003878 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3879 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003880 */
Mark Hammond08501372001-01-31 07:30:29 +00003881 char modulepath[_MAX_PATH];
3882 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003883 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3884 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003885 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003886 x = i+1;
3887 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003888 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003889 strncat(modulepath,
3890 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003891 (sizeof(modulepath)/sizeof(modulepath[0]))
3892 -strlen(modulepath));
3893 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003894 /* Eeek - file-not-found - possibly an embedding
3895 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003896 */
Tim Peters5aa91602002-01-30 05:46:57 +00003897 strncpy(modulepath,
3898 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003899 sizeof(modulepath)/sizeof(modulepath[0]));
3900 if (modulepath[strlen(modulepath)-1] != '\\')
3901 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003902 strncat(modulepath,
3903 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003904 (sizeof(modulepath)/sizeof(modulepath[0]))
3905 -strlen(modulepath));
3906 /* No where else to look - raise an easily identifiable
3907 error, rather than leaving Windows to report
3908 "file not found" - as the user is probably blissfully
3909 unaware this shim EXE is used, and it will confuse them.
3910 (well, it confused me for a while ;-)
3911 */
3912 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003913 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003914 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003915 "for popen to work with your shell "
3916 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003917 szConsoleSpawn);
3918 return FALSE;
3919 }
3920 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003921 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003922 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003923 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003924
Tim Peters92e4dd82002-10-05 01:47:34 +00003925 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003926 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003927 /* To maintain correct argument passing semantics,
3928 we pass the command-line as it stands, and allow
3929 quoting to be applied. w9xpopen.exe will then
3930 use its argv vector, and re-quote the necessary
3931 args for the ultimate child process.
3932 */
Tim Peters75cdad52001-11-28 22:07:30 +00003933 PyOS_snprintf(
3934 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003935 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003936 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003937 s1,
3938 s3,
3939 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003940 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00003941 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003942 dialog:
3943 "Your program accessed mem currently in use at xxx"
3944 and a hopeful warning about the stability of your
3945 system.
3946 Cost is Ctrl+C wont kill children, but anyone
3947 who cares can have a go!
3948 */
3949 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003950 }
3951 }
3952
3953 /* Could be an else here to try cmd.exe / command.com in the path
3954 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003955 else {
Tim Peters402d5982001-08-27 06:37:48 +00003956 PyErr_SetString(PyExc_RuntimeError,
3957 "Cannot locate a COMSPEC environment variable to "
3958 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003959 return FALSE;
3960 }
Tim Peters5aa91602002-01-30 05:46:57 +00003961
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003962 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3963 siStartInfo.cb = sizeof(STARTUPINFO);
3964 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3965 siStartInfo.hStdInput = hStdin;
3966 siStartInfo.hStdOutput = hStdout;
3967 siStartInfo.hStdError = hStderr;
3968 siStartInfo.wShowWindow = SW_HIDE;
3969
3970 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003971 s2,
3972 NULL,
3973 NULL,
3974 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003975 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003976 NULL,
3977 NULL,
3978 &siStartInfo,
3979 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003980 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003981 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003982
Mark Hammondb37a3732000-08-14 04:47:33 +00003983 /* Return process handle */
3984 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003985 return TRUE;
3986 }
Tim Peters402d5982001-08-27 06:37:48 +00003987 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003988 return FALSE;
3989}
3990
3991/* The following code is based off of KB: Q190351 */
3992
3993static PyObject *
3994_PyPopen(char *cmdstring, int mode, int n)
3995{
3996 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3997 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003998 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003999
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004000 SECURITY_ATTRIBUTES saAttr;
4001 BOOL fSuccess;
4002 int fd1, fd2, fd3;
4003 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004004 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004005 PyObject *f;
4006
4007 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4008 saAttr.bInheritHandle = TRUE;
4009 saAttr.lpSecurityDescriptor = NULL;
4010
4011 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4012 return win32_error("CreatePipe", NULL);
4013
4014 /* Create new output read handle and the input write handle. Set
4015 * the inheritance properties to FALSE. Otherwise, the child inherits
4016 * the these handles; resulting in non-closeable handles to the pipes
4017 * being created. */
4018 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004019 GetCurrentProcess(), &hChildStdinWrDup, 0,
4020 FALSE,
4021 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004022 if (!fSuccess)
4023 return win32_error("DuplicateHandle", NULL);
4024
4025 /* Close the inheritable version of ChildStdin
4026 that we're using. */
4027 CloseHandle(hChildStdinWr);
4028
4029 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4030 return win32_error("CreatePipe", NULL);
4031
4032 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004033 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4034 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004035 if (!fSuccess)
4036 return win32_error("DuplicateHandle", NULL);
4037
4038 /* Close the inheritable version of ChildStdout
4039 that we're using. */
4040 CloseHandle(hChildStdoutRd);
4041
4042 if (n != POPEN_4) {
4043 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4044 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004045 fSuccess = DuplicateHandle(GetCurrentProcess(),
4046 hChildStderrRd,
4047 GetCurrentProcess(),
4048 &hChildStderrRdDup, 0,
4049 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004050 if (!fSuccess)
4051 return win32_error("DuplicateHandle", NULL);
4052 /* Close the inheritable version of ChildStdErr that we're using. */
4053 CloseHandle(hChildStderrRd);
4054 }
Tim Peters5aa91602002-01-30 05:46:57 +00004055
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004056 switch (n) {
4057 case POPEN_1:
4058 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4059 case _O_WRONLY | _O_TEXT:
4060 /* Case for writing to child Stdin in text mode. */
4061 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4062 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004063 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004064 PyFile_SetBufSize(f, 0);
4065 /* We don't care about these pipes anymore, so close them. */
4066 CloseHandle(hChildStdoutRdDup);
4067 CloseHandle(hChildStderrRdDup);
4068 break;
4069
4070 case _O_RDONLY | _O_TEXT:
4071 /* Case for reading from child Stdout in text mode. */
4072 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4073 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004074 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004075 PyFile_SetBufSize(f, 0);
4076 /* We don't care about these pipes anymore, so close them. */
4077 CloseHandle(hChildStdinWrDup);
4078 CloseHandle(hChildStderrRdDup);
4079 break;
4080
4081 case _O_RDONLY | _O_BINARY:
4082 /* Case for readinig from child Stdout in binary mode. */
4083 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4084 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004085 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004086 PyFile_SetBufSize(f, 0);
4087 /* We don't care about these pipes anymore, so close them. */
4088 CloseHandle(hChildStdinWrDup);
4089 CloseHandle(hChildStderrRdDup);
4090 break;
4091
4092 case _O_WRONLY | _O_BINARY:
4093 /* Case for writing to child Stdin in binary mode. */
4094 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4095 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004096 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004097 PyFile_SetBufSize(f, 0);
4098 /* We don't care about these pipes anymore, so close them. */
4099 CloseHandle(hChildStdoutRdDup);
4100 CloseHandle(hChildStderrRdDup);
4101 break;
4102 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004103 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004104 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004105
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004106 case POPEN_2:
4107 case POPEN_4:
4108 {
4109 char *m1, *m2;
4110 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004111
Tim Peters7dca21e2002-08-19 00:42:29 +00004112 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004113 m1 = "r";
4114 m2 = "w";
4115 } else {
4116 m1 = "rb";
4117 m2 = "wb";
4118 }
4119
4120 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4121 f1 = _fdopen(fd1, m2);
4122 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4123 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004124 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004125 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004126 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004127 PyFile_SetBufSize(p2, 0);
4128
4129 if (n != 4)
4130 CloseHandle(hChildStderrRdDup);
4131
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004132 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004133 Py_XDECREF(p1);
4134 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004135 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004136 break;
4137 }
Tim Peters5aa91602002-01-30 05:46:57 +00004138
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004139 case POPEN_3:
4140 {
4141 char *m1, *m2;
4142 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004143
Tim Peters7dca21e2002-08-19 00:42:29 +00004144 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004145 m1 = "r";
4146 m2 = "w";
4147 } else {
4148 m1 = "rb";
4149 m2 = "wb";
4150 }
4151
4152 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4153 f1 = _fdopen(fd1, m2);
4154 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4155 f2 = _fdopen(fd2, m1);
4156 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4157 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004158 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004159 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4160 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 PyFile_SetBufSize(p1, 0);
4162 PyFile_SetBufSize(p2, 0);
4163 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004164 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004165 Py_XDECREF(p1);
4166 Py_XDECREF(p2);
4167 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004168 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004169 break;
4170 }
4171 }
4172
4173 if (n == POPEN_4) {
4174 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004175 hChildStdinRd,
4176 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004177 hChildStdoutWr,
4178 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004179 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004180 }
4181 else {
4182 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004183 hChildStdinRd,
4184 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004185 hChildStderrWr,
4186 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004187 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004188 }
4189
Mark Hammondb37a3732000-08-14 04:47:33 +00004190 /*
4191 * Insert the files we've created into the process dictionary
4192 * all referencing the list with the process handle and the
4193 * initial number of files (see description below in _PyPclose).
4194 * Since if _PyPclose later tried to wait on a process when all
4195 * handles weren't closed, it could create a deadlock with the
4196 * child, we spend some energy here to try to ensure that we
4197 * either insert all file handles into the dictionary or none
4198 * at all. It's a little clumsy with the various popen modes
4199 * and variable number of files involved.
4200 */
4201 if (!_PyPopenProcs) {
4202 _PyPopenProcs = PyDict_New();
4203 }
4204
4205 if (_PyPopenProcs) {
4206 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4207 int ins_rc[3];
4208
4209 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4210 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4211
4212 procObj = PyList_New(2);
4213 hProcessObj = PyLong_FromVoidPtr(hProcess);
4214 intObj = PyInt_FromLong(file_count);
4215
4216 if (procObj && hProcessObj && intObj) {
4217 PyList_SetItem(procObj,0,hProcessObj);
4218 PyList_SetItem(procObj,1,intObj);
4219
4220 fileObj[0] = PyLong_FromVoidPtr(f1);
4221 if (fileObj[0]) {
4222 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4223 fileObj[0],
4224 procObj);
4225 }
4226 if (file_count >= 2) {
4227 fileObj[1] = PyLong_FromVoidPtr(f2);
4228 if (fileObj[1]) {
4229 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4230 fileObj[1],
4231 procObj);
4232 }
4233 }
4234 if (file_count >= 3) {
4235 fileObj[2] = PyLong_FromVoidPtr(f3);
4236 if (fileObj[2]) {
4237 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4238 fileObj[2],
4239 procObj);
4240 }
4241 }
4242
4243 if (ins_rc[0] < 0 || !fileObj[0] ||
4244 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4245 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4246 /* Something failed - remove any dictionary
4247 * entries that did make it.
4248 */
4249 if (!ins_rc[0] && fileObj[0]) {
4250 PyDict_DelItem(_PyPopenProcs,
4251 fileObj[0]);
4252 }
4253 if (!ins_rc[1] && fileObj[1]) {
4254 PyDict_DelItem(_PyPopenProcs,
4255 fileObj[1]);
4256 }
4257 if (!ins_rc[2] && fileObj[2]) {
4258 PyDict_DelItem(_PyPopenProcs,
4259 fileObj[2]);
4260 }
4261 }
4262 }
Tim Peters5aa91602002-01-30 05:46:57 +00004263
Mark Hammondb37a3732000-08-14 04:47:33 +00004264 /*
4265 * Clean up our localized references for the dictionary keys
4266 * and value since PyDict_SetItem will Py_INCREF any copies
4267 * that got placed in the dictionary.
4268 */
4269 Py_XDECREF(procObj);
4270 Py_XDECREF(fileObj[0]);
4271 Py_XDECREF(fileObj[1]);
4272 Py_XDECREF(fileObj[2]);
4273 }
4274
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004275 /* Child is launched. Close the parents copy of those pipe
4276 * handles that only the child should have open. You need to
4277 * make sure that no handles to the write end of the output pipe
4278 * are maintained in this process or else the pipe will not close
4279 * when the child process exits and the ReadFile will hang. */
4280
4281 if (!CloseHandle(hChildStdinRd))
4282 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004283
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004284 if (!CloseHandle(hChildStdoutWr))
4285 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004286
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004287 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4288 return win32_error("CloseHandle", NULL);
4289
4290 return f;
4291}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004292
4293/*
4294 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4295 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004296 *
4297 * This function uses the _PyPopenProcs dictionary in order to map the
4298 * input file pointer to information about the process that was
4299 * originally created by the popen* call that created the file pointer.
4300 * The dictionary uses the file pointer as a key (with one entry
4301 * inserted for each file returned by the original popen* call) and a
4302 * single list object as the value for all files from a single call.
4303 * The list object contains the Win32 process handle at [0], and a file
4304 * count at [1], which is initialized to the total number of file
4305 * handles using that list.
4306 *
4307 * This function closes whichever handle it is passed, and decrements
4308 * the file count in the dictionary for the process handle pointed to
4309 * by this file. On the last close (when the file count reaches zero),
4310 * this function will wait for the child process and then return its
4311 * exit code as the result of the close() operation. This permits the
4312 * files to be closed in any order - it is always the close() of the
4313 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004314 *
4315 * NOTE: This function is currently called with the GIL released.
4316 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004317 */
Tim Peters736aa322000-09-01 06:51:24 +00004318
Fredrik Lundh56055a42000-07-23 19:47:12 +00004319static int _PyPclose(FILE *file)
4320{
Fredrik Lundh20318932000-07-26 17:29:12 +00004321 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004322 DWORD exit_code;
4323 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004324 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4325 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004326#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004327 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004328#endif
4329
Fredrik Lundh20318932000-07-26 17:29:12 +00004330 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004331 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004332 */
4333 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004334#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004335 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004336#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004337 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004338 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4339 (procObj = PyDict_GetItem(_PyPopenProcs,
4340 fileObj)) != NULL &&
4341 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4342 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4343
4344 hProcess = PyLong_AsVoidPtr(hProcessObj);
4345 file_count = PyInt_AsLong(intObj);
4346
4347 if (file_count > 1) {
4348 /* Still other files referencing process */
4349 file_count--;
4350 PyList_SetItem(procObj,1,
4351 PyInt_FromLong(file_count));
4352 } else {
4353 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004354 if (result != EOF &&
4355 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4356 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004357 /* Possible truncation here in 16-bit environments, but
4358 * real exit codes are just the lower byte in any event.
4359 */
4360 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004361 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004362 /* Indicate failure - this will cause the file object
4363 * to raise an I/O error and translate the last Win32
4364 * error code from errno. We do have a problem with
4365 * last errors that overlap the normal errno table,
4366 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004367 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004368 if (result != EOF) {
4369 /* If the error wasn't from the fclose(), then
4370 * set errno for the file object error handling.
4371 */
4372 errno = GetLastError();
4373 }
4374 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004375 }
4376
4377 /* Free up the native handle at this point */
4378 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004379 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004380
Mark Hammondb37a3732000-08-14 04:47:33 +00004381 /* Remove this file pointer from dictionary */
4382 PyDict_DelItem(_PyPopenProcs, fileObj);
4383
4384 if (PyDict_Size(_PyPopenProcs) == 0) {
4385 Py_DECREF(_PyPopenProcs);
4386 _PyPopenProcs = NULL;
4387 }
4388
4389 } /* if object retrieval ok */
4390
4391 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004392 } /* if _PyPopenProcs */
4393
Tim Peters736aa322000-09-01 06:51:24 +00004394#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004395 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004396#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004397 return result;
4398}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004399
4400#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004402posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004403{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004404 char *name;
4405 char *mode = "r";
4406 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004407 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004408 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004409 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004410 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004411 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004412 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004413 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004414 if (fp == NULL)
4415 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004416 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004417 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004418 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004419 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004420}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004421
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004422#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004423#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004425
Guido van Rossumb6775db1994-08-01 11:34:53 +00004426#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004427PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004428"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004429Set the current process's user id.");
4430
Barry Warsaw53699e91996-12-10 23:23:01 +00004431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004432posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004433{
4434 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004435 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004436 return NULL;
4437 if (setuid(uid) < 0)
4438 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004439 Py_INCREF(Py_None);
4440 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004441}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004442#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004443
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004444
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004445#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004446PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004447"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004448Set the current process's effective user id.");
4449
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004450static PyObject *
4451posix_seteuid (PyObject *self, PyObject *args)
4452{
4453 int euid;
4454 if (!PyArg_ParseTuple(args, "i", &euid)) {
4455 return NULL;
4456 } else if (seteuid(euid) < 0) {
4457 return posix_error();
4458 } else {
4459 Py_INCREF(Py_None);
4460 return Py_None;
4461 }
4462}
4463#endif /* HAVE_SETEUID */
4464
4465#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004467"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468Set the current process's effective group id.");
4469
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004470static PyObject *
4471posix_setegid (PyObject *self, PyObject *args)
4472{
4473 int egid;
4474 if (!PyArg_ParseTuple(args, "i", &egid)) {
4475 return NULL;
4476 } else if (setegid(egid) < 0) {
4477 return posix_error();
4478 } else {
4479 Py_INCREF(Py_None);
4480 return Py_None;
4481 }
4482}
4483#endif /* HAVE_SETEGID */
4484
4485#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004486PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004487"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004488Set the current process's real and effective user ids.");
4489
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004490static PyObject *
4491posix_setreuid (PyObject *self, PyObject *args)
4492{
4493 int ruid, euid;
4494 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4495 return NULL;
4496 } else if (setreuid(ruid, euid) < 0) {
4497 return posix_error();
4498 } else {
4499 Py_INCREF(Py_None);
4500 return Py_None;
4501 }
4502}
4503#endif /* HAVE_SETREUID */
4504
4505#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004506PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004507"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004508Set the current process's real and effective group ids.");
4509
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004510static PyObject *
4511posix_setregid (PyObject *self, PyObject *args)
4512{
4513 int rgid, egid;
4514 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4515 return NULL;
4516 } else if (setregid(rgid, egid) < 0) {
4517 return posix_error();
4518 } else {
4519 Py_INCREF(Py_None);
4520 return Py_None;
4521 }
4522}
4523#endif /* HAVE_SETREGID */
4524
Guido van Rossumb6775db1994-08-01 11:34:53 +00004525#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004526PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004527"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004528Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004529
Barry Warsaw53699e91996-12-10 23:23:01 +00004530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004531posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004532{
4533 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004534 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004535 return NULL;
4536 if (setgid(gid) < 0)
4537 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004538 Py_INCREF(Py_None);
4539 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004540}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004541#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004542
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004543#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004544PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004545"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004546Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004547
4548static PyObject *
4549posix_setgroups(PyObject *self, PyObject *args)
4550{
4551 PyObject *groups;
4552 int i, len;
4553 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004554
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004555 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4556 return NULL;
4557 if (!PySequence_Check(groups)) {
4558 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4559 return NULL;
4560 }
4561 len = PySequence_Size(groups);
4562 if (len > MAX_GROUPS) {
4563 PyErr_SetString(PyExc_ValueError, "too many groups");
4564 return NULL;
4565 }
4566 for(i = 0; i < len; i++) {
4567 PyObject *elem;
4568 elem = PySequence_GetItem(groups, i);
4569 if (!elem)
4570 return NULL;
4571 if (!PyInt_Check(elem)) {
4572 PyErr_SetString(PyExc_TypeError,
4573 "groups must be integers");
4574 Py_DECREF(elem);
4575 return NULL;
4576 }
4577 /* XXX: check that value fits into gid_t. */
4578 grouplist[i] = PyInt_AsLong(elem);
4579 Py_DECREF(elem);
4580 }
4581
4582 if (setgroups(len, grouplist) < 0)
4583 return posix_error();
4584 Py_INCREF(Py_None);
4585 return Py_None;
4586}
4587#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004588
Guido van Rossumb6775db1994-08-01 11:34:53 +00004589#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004591"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004592Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Barry Warsaw53699e91996-12-10 23:23:01 +00004594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004595posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004596{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004597 int pid, options;
4598#ifdef UNION_WAIT
4599 union wait status;
4600#define status_i (status.w_status)
4601#else
4602 int status;
4603#define status_i status
4604#endif
4605 status_i = 0;
4606
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004607 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004608 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004609 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004610 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004611 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004612 if (pid == -1)
4613 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004614 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004615 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004616}
4617
Tim Petersab034fa2002-02-01 11:27:43 +00004618#elif defined(HAVE_CWAIT)
4619
4620/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004621PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004622"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004623"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004624
4625static PyObject *
4626posix_waitpid(PyObject *self, PyObject *args)
4627{
4628 int pid, options;
4629 int status;
4630
4631 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4632 return NULL;
4633 Py_BEGIN_ALLOW_THREADS
4634 pid = _cwait(&status, pid, options);
4635 Py_END_ALLOW_THREADS
4636 if (pid == -1)
4637 return posix_error();
4638 else
4639 /* shift the status left a byte so this is more like the
4640 POSIX waitpid */
4641 return Py_BuildValue("ii", pid, status << 8);
4642}
4643#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004644
Guido van Rossumad0ee831995-03-01 10:34:45 +00004645#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004646PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004647"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004648Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004649
Barry Warsaw53699e91996-12-10 23:23:01 +00004650static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004651posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004652{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004653 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004654#ifdef UNION_WAIT
4655 union wait status;
4656#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004657#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004658 int status;
4659#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004660#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004661
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004662 status_i = 0;
4663 Py_BEGIN_ALLOW_THREADS
4664 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004665 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004666 if (pid == -1)
4667 return posix_error();
4668 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004669 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004670#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004671}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004672#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004675PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004676"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004677Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004678
Barry Warsaw53699e91996-12-10 23:23:01 +00004679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004680posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004681{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004682#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004683 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004684#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004685#ifdef MS_WINDOWS
4686 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4687#else
4688 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4689#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004690#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004691}
4692
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004693
Guido van Rossumb6775db1994-08-01 11:34:53 +00004694#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004695PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004696"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004697Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004698
Barry Warsaw53699e91996-12-10 23:23:01 +00004699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004700posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004701{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004702 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004703 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004704 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004705 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004706 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004707 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004708 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004709 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004710 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004711 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004712 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004713}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004714#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004716
Guido van Rossumb6775db1994-08-01 11:34:53 +00004717#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004718PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004719"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004720Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004721
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004723posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004724{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004725 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004726}
4727#endif /* HAVE_SYMLINK */
4728
4729
4730#ifdef HAVE_TIMES
4731#ifndef HZ
4732#define HZ 60 /* Universal constant :-) */
4733#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004734
Guido van Rossumd48f2521997-12-05 22:19:34 +00004735#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4736static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004737system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004738{
4739 ULONG value = 0;
4740
4741 Py_BEGIN_ALLOW_THREADS
4742 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4743 Py_END_ALLOW_THREADS
4744
4745 return value;
4746}
4747
4748static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004749posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004750{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004751 /* Currently Only Uptime is Provided -- Others Later */
4752 return Py_BuildValue("ddddd",
4753 (double)0 /* t.tms_utime / HZ */,
4754 (double)0 /* t.tms_stime / HZ */,
4755 (double)0 /* t.tms_cutime / HZ */,
4756 (double)0 /* t.tms_cstime / HZ */,
4757 (double)system_uptime() / 1000);
4758}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004759#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004760static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004761posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004762{
4763 struct tms t;
4764 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004765 errno = 0;
4766 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004767 if (c == (clock_t) -1)
4768 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004769 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004770 (double)t.tms_utime / HZ,
4771 (double)t.tms_stime / HZ,
4772 (double)t.tms_cutime / HZ,
4773 (double)t.tms_cstime / HZ,
4774 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004775}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004776#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004777#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004778
4779
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004780#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004781#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004782static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004783posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004784{
4785 FILETIME create, exit, kernel, user;
4786 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004787 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004788 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4789 /* The fields of a FILETIME structure are the hi and lo part
4790 of a 64-bit value expressed in 100 nanosecond units.
4791 1e7 is one second in such units; 1e-7 the inverse.
4792 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4793 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004794 return Py_BuildValue(
4795 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004796 (double)(kernel.dwHighDateTime*429.4967296 +
4797 kernel.dwLowDateTime*1e-7),
4798 (double)(user.dwHighDateTime*429.4967296 +
4799 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004800 (double)0,
4801 (double)0,
4802 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004803}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004804#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004805
4806#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004807PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004808"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004809Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004810#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004812
Guido van Rossumb6775db1994-08-01 11:34:53 +00004813#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004815"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004816Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004817
Barry Warsaw53699e91996-12-10 23:23:01 +00004818static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004819posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004820{
Guido van Rossum687dd131993-05-17 08:34:16 +00004821 if (setsid() < 0)
4822 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004823 Py_INCREF(Py_None);
4824 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004825}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004826#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004827
Guido van Rossumb6775db1994-08-01 11:34:53 +00004828#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004830"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004832
Barry Warsaw53699e91996-12-10 23:23:01 +00004833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004834posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004835{
4836 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004837 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004838 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004839 if (setpgid(pid, pgrp) < 0)
4840 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004841 Py_INCREF(Py_None);
4842 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004843}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004844#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004846
Guido van Rossumb6775db1994-08-01 11:34:53 +00004847#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004848PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004849"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004850Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004851
Barry Warsaw53699e91996-12-10 23:23:01 +00004852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004853posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004854{
4855 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004856 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004857 return NULL;
4858 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004859 if (pgid < 0)
4860 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004861 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004862}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004863#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004865
Guido van Rossumb6775db1994-08-01 11:34:53 +00004866#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004867PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004868"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004869Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004870
Barry Warsaw53699e91996-12-10 23:23:01 +00004871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004872posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004873{
4874 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004875 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004876 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004877 if (tcsetpgrp(fd, pgid) < 0)
4878 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004879 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004880 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004881}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004882#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004883
Guido van Rossum687dd131993-05-17 08:34:16 +00004884/* Functions acting on file descriptors */
4885
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004886PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004887"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004888Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004889
Barry Warsaw53699e91996-12-10 23:23:01 +00004890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004891posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004892{
Mark Hammondef8b6542001-05-13 08:04:26 +00004893 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004894 int flag;
4895 int mode = 0777;
4896 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004897
4898#ifdef MS_WINDOWS
4899 if (unicode_file_names()) {
4900 PyUnicodeObject *po;
4901 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4902 Py_BEGIN_ALLOW_THREADS
4903 /* PyUnicode_AS_UNICODE OK without thread
4904 lock as it is a simple dereference. */
4905 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4906 Py_END_ALLOW_THREADS
4907 if (fd < 0)
4908 return posix_error();
4909 return PyInt_FromLong((long)fd);
4910 }
4911 /* Drop the argument parsing error as narrow strings
4912 are also valid. */
4913 PyErr_Clear();
4914 }
4915#endif
4916
Tim Peters5aa91602002-01-30 05:46:57 +00004917 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004918 Py_FileSystemDefaultEncoding, &file,
4919 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004920 return NULL;
4921
Barry Warsaw53699e91996-12-10 23:23:01 +00004922 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004923 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004924 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004925 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004926 return posix_error_with_allocated_filename(file);
4927 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004928 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004929}
4930
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004931
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Barry Warsaw53699e91996-12-10 23:23:01 +00004936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004937posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004938{
4939 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004940 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004941 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004942 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004943 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004944 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004945 if (res < 0)
4946 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004947 Py_INCREF(Py_None);
4948 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004949}
4950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004951
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004952PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004953"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004954Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004955
Barry Warsaw53699e91996-12-10 23:23:01 +00004956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004957posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004958{
4959 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004960 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004962 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004963 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004964 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004965 if (fd < 0)
4966 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004967 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004968}
4969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004971PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004972"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004973Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004974
Barry Warsaw53699e91996-12-10 23:23:01 +00004975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004976posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004977{
4978 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004979 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004980 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004982 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004983 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004984 if (res < 0)
4985 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004986 Py_INCREF(Py_None);
4987 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004988}
4989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004990
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004992"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004994
Barry Warsaw53699e91996-12-10 23:23:01 +00004995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004996posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004997{
4998 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004999#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005000 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005001#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005002 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005003#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005004 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 return NULL;
5007#ifdef SEEK_SET
5008 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5009 switch (how) {
5010 case 0: how = SEEK_SET; break;
5011 case 1: how = SEEK_CUR; break;
5012 case 2: how = SEEK_END; break;
5013 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005014#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005015
5016#if !defined(HAVE_LARGEFILE_SUPPORT)
5017 pos = PyInt_AsLong(posobj);
5018#else
5019 pos = PyLong_Check(posobj) ?
5020 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5021#endif
5022 if (PyErr_Occurred())
5023 return NULL;
5024
Barry Warsaw53699e91996-12-10 23:23:01 +00005025 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005026#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005027 res = _lseeki64(fd, pos, how);
5028#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005029 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005030#endif
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();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005034
5035#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005036 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005037#else
5038 return PyLong_FromLongLong(res);
5039#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005040}
5041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005044"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005046
Barry Warsaw53699e91996-12-10 23:23:01 +00005047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005048posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005049{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005050 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005051 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005052 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005053 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005055 if (buffer == NULL)
5056 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005057 Py_BEGIN_ALLOW_THREADS
5058 n = read(fd, PyString_AsString(buffer), size);
5059 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005060 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005061 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 return posix_error();
5063 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005064 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005065 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005066 return buffer;
5067}
5068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005070PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005071"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005072Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005073
Barry Warsaw53699e91996-12-10 23:23:01 +00005074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005075posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005076{
5077 int fd, size;
5078 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005079 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005080 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005081 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005082 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005083 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005084 if (size < 0)
5085 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005086 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005087}
5088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005090PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005091"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005092Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005093
Barry Warsaw53699e91996-12-10 23:23:01 +00005094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005095posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005096{
5097 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005098 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005099 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005100 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005101 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005102#ifdef __VMS
5103 /* on OpenVMS we must ensure that all bytes are written to the file */
5104 fsync(fd);
5105#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005106 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005107 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005108 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005109 if (res != 0)
5110 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005111
Fred Drake699f3522000-06-29 21:12:41 +00005112 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005113}
5114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005115
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005117"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005119
Barry Warsaw53699e91996-12-10 23:23:01 +00005120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005121posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005122{
Guido van Rossum687dd131993-05-17 08:34:16 +00005123 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005124 char *mode = "r";
5125 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005126 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005127 PyObject *f;
5128 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005129 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005130
Thomas Heller1f043e22002-11-07 16:00:59 +00005131 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5132 PyErr_Format(PyExc_ValueError,
5133 "invalid file mode '%s'", mode);
5134 return NULL;
5135 }
5136
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005138 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005139 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005140 if (fp == NULL)
5141 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005142 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005143 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005144 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005145 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005146}
5147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005149"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005150Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005151connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005152
5153static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005154posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005155{
5156 int fd;
5157 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5158 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005159 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005160}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005161
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005162#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005163PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005164"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005165Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005166
Barry Warsaw53699e91996-12-10 23:23:01 +00005167static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005168posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005169{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005170#if defined(PYOS_OS2)
5171 HFILE read, write;
5172 APIRET rc;
5173
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005174 Py_BEGIN_ALLOW_THREADS
5175 rc = DosCreatePipe( &read, &write, 4096);
5176 Py_END_ALLOW_THREADS
5177 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005178 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005179
5180 return Py_BuildValue("(ii)", read, write);
5181#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005182#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005183 int fds[2];
5184 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005186#if defined(__VMS)
5187 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5188#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005189 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005190#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005191 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005192 if (res != 0)
5193 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005194 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005195#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005196 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005197 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005198 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005199 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005200 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005201 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005202 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005203 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005204 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5205 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005206 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005207#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005208#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005209}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005210#endif /* HAVE_PIPE */
5211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005212
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005213#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005215"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005217
Barry Warsaw53699e91996-12-10 23:23:01 +00005218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005219posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005220{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005221 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005222 int mode = 0666;
5223 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005224 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005225 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005226 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005227 res = mkfifo(filename, mode);
5228 Py_END_ALLOW_THREADS
5229 if (res < 0)
5230 return posix_error();
5231 Py_INCREF(Py_None);
5232 return Py_None;
5233}
5234#endif
5235
5236
Neal Norwitz11690112002-07-30 01:08:28 +00005237#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005239"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005240Create a filesystem node (file, device special file or named pipe)\n\
5241named filename. mode specifies both the permissions to use and the\n\
5242type of node to be created, being combined (bitwise OR) with one of\n\
5243S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005244device defines the newly created device special file (probably using\n\
5245os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005246
5247
5248static PyObject *
5249posix_mknod(PyObject *self, PyObject *args)
5250{
5251 char *filename;
5252 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005253 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005254 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005255 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005256 return NULL;
5257 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005258 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005259 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005260 if (res < 0)
5261 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005262 Py_INCREF(Py_None);
5263 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005264}
5265#endif
5266
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005267#ifdef HAVE_DEVICE_MACROS
5268PyDoc_STRVAR(posix_major__doc__,
5269"major(device) -> major number\n\
5270Extracts a device major number from a raw device number.");
5271
5272static PyObject *
5273posix_major(PyObject *self, PyObject *args)
5274{
5275 int device;
5276 if (!PyArg_ParseTuple(args, "i:major", &device))
5277 return NULL;
5278 return PyInt_FromLong((long)major(device));
5279}
5280
5281PyDoc_STRVAR(posix_minor__doc__,
5282"minor(device) -> minor number\n\
5283Extracts a device minor number from a raw device number.");
5284
5285static PyObject *
5286posix_minor(PyObject *self, PyObject *args)
5287{
5288 int device;
5289 if (!PyArg_ParseTuple(args, "i:minor", &device))
5290 return NULL;
5291 return PyInt_FromLong((long)minor(device));
5292}
5293
5294PyDoc_STRVAR(posix_makedev__doc__,
5295"makedev(major, minor) -> device number\n\
5296Composes a raw device number from the major and minor device numbers.");
5297
5298static PyObject *
5299posix_makedev(PyObject *self, PyObject *args)
5300{
5301 int major, minor;
5302 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5303 return NULL;
5304 return PyInt_FromLong((long)makedev(major, minor));
5305}
5306#endif /* device macros */
5307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005308
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005309#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005310PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005311"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005312Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005313
Barry Warsaw53699e91996-12-10 23:23:01 +00005314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005315posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005316{
5317 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005318 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005319 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005320 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005321
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005322 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005323 return NULL;
5324
5325#if !defined(HAVE_LARGEFILE_SUPPORT)
5326 length = PyInt_AsLong(lenobj);
5327#else
5328 length = PyLong_Check(lenobj) ?
5329 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5330#endif
5331 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005332 return NULL;
5333
Barry Warsaw53699e91996-12-10 23:23:01 +00005334 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005335 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005336 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005337 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005338 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005339 return NULL;
5340 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005341 Py_INCREF(Py_None);
5342 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005343}
5344#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005345
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005346#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005347PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005348"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005350
Fred Drake762e2061999-08-26 17:23:54 +00005351/* Save putenv() parameters as values here, so we can collect them when they
5352 * get re-set with another call for the same key. */
5353static PyObject *posix_putenv_garbage;
5354
Tim Peters5aa91602002-01-30 05:46:57 +00005355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005356posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005357{
5358 char *s1, *s2;
5359 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005360 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005361 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005362
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005364 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005365
5366#if defined(PYOS_OS2)
5367 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5368 APIRET rc;
5369
Guido van Rossumd48f2521997-12-05 22:19:34 +00005370 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5371 if (rc != NO_ERROR)
5372 return os2_error(rc);
5373
5374 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5375 APIRET rc;
5376
Guido van Rossumd48f2521997-12-05 22:19:34 +00005377 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5378 if (rc != NO_ERROR)
5379 return os2_error(rc);
5380 } else {
5381#endif
5382
Fred Drake762e2061999-08-26 17:23:54 +00005383 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005384 len = strlen(s1) + strlen(s2) + 2;
5385 /* len includes space for a trailing \0; the size arg to
5386 PyString_FromStringAndSize does not count that */
5387 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005388 if (newstr == NULL)
5389 return PyErr_NoMemory();
5390 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005391 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005392 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005393 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005394 posix_error();
5395 return NULL;
5396 }
Fred Drake762e2061999-08-26 17:23:54 +00005397 /* Install the first arg and newstr in posix_putenv_garbage;
5398 * this will cause previous value to be collected. This has to
5399 * happen after the real putenv() call because the old value
5400 * was still accessible until then. */
5401 if (PyDict_SetItem(posix_putenv_garbage,
5402 PyTuple_GET_ITEM(args, 0), newstr)) {
5403 /* really not much we can do; just leak */
5404 PyErr_Clear();
5405 }
5406 else {
5407 Py_DECREF(newstr);
5408 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005409
5410#if defined(PYOS_OS2)
5411 }
5412#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005413 Py_INCREF(Py_None);
5414 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005415}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005416#endif /* putenv */
5417
Guido van Rossumc524d952001-10-19 01:31:59 +00005418#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005422
5423static PyObject *
5424posix_unsetenv(PyObject *self, PyObject *args)
5425{
5426 char *s1;
5427
5428 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5429 return NULL;
5430
5431 unsetenv(s1);
5432
5433 /* Remove the key from posix_putenv_garbage;
5434 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005435 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005436 * old value was still accessible until then.
5437 */
5438 if (PyDict_DelItem(posix_putenv_garbage,
5439 PyTuple_GET_ITEM(args, 0))) {
5440 /* really not much we can do; just leak */
5441 PyErr_Clear();
5442 }
5443
5444 Py_INCREF(Py_None);
5445 return Py_None;
5446}
5447#endif /* unsetenv */
5448
Guido van Rossumb6a47161997-09-15 22:54:34 +00005449#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005451"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005452Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005453
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005455posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005456{
5457 int code;
5458 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005459 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005460 return NULL;
5461 message = strerror(code);
5462 if (message == NULL) {
5463 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005464 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005465 return NULL;
5466 }
5467 return PyString_FromString(message);
5468}
5469#endif /* strerror */
5470
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005471
Guido van Rossumc9641791998-08-04 15:26:23 +00005472#ifdef HAVE_SYS_WAIT_H
5473
Fred Drake106c1a02002-04-23 15:58:02 +00005474#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005475PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005476"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005477Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005478
5479static PyObject *
5480posix_WCOREDUMP(PyObject *self, PyObject *args)
5481{
5482#ifdef UNION_WAIT
5483 union wait status;
5484#define status_i (status.w_status)
5485#else
5486 int status;
5487#define status_i status
5488#endif
5489 status_i = 0;
5490
5491 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5492 {
5493 return NULL;
5494 }
5495
5496 return PyBool_FromLong(WCOREDUMP(status));
5497#undef status_i
5498}
5499#endif /* WCOREDUMP */
5500
5501#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005504Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005506
5507static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005508posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005509{
5510#ifdef UNION_WAIT
5511 union wait status;
5512#define status_i (status.w_status)
5513#else
5514 int status;
5515#define status_i status
5516#endif
5517 status_i = 0;
5518
5519 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5520 {
5521 return NULL;
5522 }
5523
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005524 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005525#undef status_i
5526}
5527#endif /* WIFCONTINUED */
5528
Guido van Rossumc9641791998-08-04 15:26:23 +00005529#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005531"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005532Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005533
5534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005535posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005536{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005537#ifdef UNION_WAIT
5538 union wait status;
5539#define status_i (status.w_status)
5540#else
5541 int status;
5542#define status_i status
5543#endif
5544 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005545
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005546 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005547 {
5548 return NULL;
5549 }
Tim Peters5aa91602002-01-30 05:46:57 +00005550
Fred Drake106c1a02002-04-23 15:58:02 +00005551 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005553}
5554#endif /* WIFSTOPPED */
5555
5556#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005560
5561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005562posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005563{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005564#ifdef UNION_WAIT
5565 union wait status;
5566#define status_i (status.w_status)
5567#else
5568 int status;
5569#define status_i status
5570#endif
5571 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005572
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005574 {
5575 return NULL;
5576 }
Tim Peters5aa91602002-01-30 05:46:57 +00005577
Fred Drake106c1a02002-04-23 15:58:02 +00005578 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005579#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005580}
5581#endif /* WIFSIGNALED */
5582
5583#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005584PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005585"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005586Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005588
5589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005590posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005591{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005592#ifdef UNION_WAIT
5593 union wait status;
5594#define status_i (status.w_status)
5595#else
5596 int status;
5597#define status_i status
5598#endif
5599 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005600
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005601 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005602 {
5603 return NULL;
5604 }
Tim Peters5aa91602002-01-30 05:46:57 +00005605
Fred Drake106c1a02002-04-23 15:58:02 +00005606 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005607#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005608}
5609#endif /* WIFEXITED */
5610
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005611#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005613"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005615
5616static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005617posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005618{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005619#ifdef UNION_WAIT
5620 union wait status;
5621#define status_i (status.w_status)
5622#else
5623 int status;
5624#define status_i status
5625#endif
5626 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005627
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005629 {
5630 return NULL;
5631 }
Tim Peters5aa91602002-01-30 05:46:57 +00005632
Guido van Rossumc9641791998-08-04 15:26:23 +00005633 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005635}
5636#endif /* WEXITSTATUS */
5637
5638#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005639PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005640"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005641Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005642value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005643
5644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005645posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005646{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005647#ifdef UNION_WAIT
5648 union wait status;
5649#define status_i (status.w_status)
5650#else
5651 int status;
5652#define status_i status
5653#endif
5654 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005655
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005657 {
5658 return NULL;
5659 }
Tim Peters5aa91602002-01-30 05:46:57 +00005660
Guido van Rossumc9641791998-08-04 15:26:23 +00005661 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005662#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005663}
5664#endif /* WTERMSIG */
5665
5666#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005668"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669Return the signal that stopped the process that provided\n\
5670the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005671
5672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005673posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005674{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005675#ifdef UNION_WAIT
5676 union wait status;
5677#define status_i (status.w_status)
5678#else
5679 int status;
5680#define status_i status
5681#endif
5682 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005683
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005685 {
5686 return NULL;
5687 }
Tim Peters5aa91602002-01-30 05:46:57 +00005688
Guido van Rossumc9641791998-08-04 15:26:23 +00005689 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005690#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005691}
5692#endif /* WSTOPSIG */
5693
5694#endif /* HAVE_SYS_WAIT_H */
5695
5696
Guido van Rossum94f6f721999-01-06 18:42:14 +00005697#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005698#ifdef _SCO_DS
5699/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5700 needed definitions in sys/statvfs.h */
5701#define _SVID3
5702#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005703#include <sys/statvfs.h>
5704
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005705static PyObject*
5706_pystatvfs_fromstructstatvfs(struct statvfs st) {
5707 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5708 if (v == NULL)
5709 return NULL;
5710
5711#if !defined(HAVE_LARGEFILE_SUPPORT)
5712 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5713 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5714 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5715 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5716 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5717 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5718 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5719 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5720 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5721 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5722#else
5723 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5724 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005725 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005726 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005727 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005728 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005729 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005730 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005731 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005732 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005733 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005734 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005735 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005736 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005737 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5738 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5739#endif
5740
5741 return v;
5742}
5743
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005745"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005746Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005747
5748static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005749posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005750{
5751 int fd, res;
5752 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005753
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005754 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005755 return NULL;
5756 Py_BEGIN_ALLOW_THREADS
5757 res = fstatvfs(fd, &st);
5758 Py_END_ALLOW_THREADS
5759 if (res != 0)
5760 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005761
5762 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005763}
5764#endif /* HAVE_FSTATVFS */
5765
5766
5767#if defined(HAVE_STATVFS)
5768#include <sys/statvfs.h>
5769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005771"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005773
5774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005775posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005776{
5777 char *path;
5778 int res;
5779 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005780 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005781 return NULL;
5782 Py_BEGIN_ALLOW_THREADS
5783 res = statvfs(path, &st);
5784 Py_END_ALLOW_THREADS
5785 if (res != 0)
5786 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005787
5788 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005789}
5790#endif /* HAVE_STATVFS */
5791
5792
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005793#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005794PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005795"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005796Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005797The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005799
5800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005801posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005802{
5803 PyObject *result = NULL;
5804 char *dir = NULL;
5805 char *pfx = NULL;
5806 char *name;
5807
5808 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5809 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005810
5811 if (PyErr_Warn(PyExc_RuntimeWarning,
5812 "tempnam is a potential security risk to your program") < 0)
5813 return NULL;
5814
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005815#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005816 name = _tempnam(dir, pfx);
5817#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005818 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005819#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005820 if (name == NULL)
5821 return PyErr_NoMemory();
5822 result = PyString_FromString(name);
5823 free(name);
5824 return result;
5825}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005826#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005827
5828
5829#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005831"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005833
5834static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005835posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005836{
5837 FILE *fp;
5838
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005839 fp = tmpfile();
5840 if (fp == NULL)
5841 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005842 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005843}
5844#endif
5845
5846
5847#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005848PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005849"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005850Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005851
5852static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005853posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005854{
5855 char buffer[L_tmpnam];
5856 char *name;
5857
Skip Montanaro95618b52001-08-18 18:52:10 +00005858 if (PyErr_Warn(PyExc_RuntimeWarning,
5859 "tmpnam is a potential security risk to your program") < 0)
5860 return NULL;
5861
Greg Wardb48bc172000-03-01 21:51:56 +00005862#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005863 name = tmpnam_r(buffer);
5864#else
5865 name = tmpnam(buffer);
5866#endif
5867 if (name == NULL) {
5868 PyErr_SetObject(PyExc_OSError,
5869 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005870#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005871 "unexpected NULL from tmpnam_r"
5872#else
5873 "unexpected NULL from tmpnam"
5874#endif
5875 ));
5876 return NULL;
5877 }
5878 return PyString_FromString(buffer);
5879}
5880#endif
5881
5882
Fred Drakec9680921999-12-13 16:37:25 +00005883/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5884 * It maps strings representing configuration variable names to
5885 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005886 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005887 * rarely-used constants. There are three separate tables that use
5888 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005889 *
5890 * This code is always included, even if none of the interfaces that
5891 * need it are included. The #if hackery needed to avoid it would be
5892 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005893 */
5894struct constdef {
5895 char *name;
5896 long value;
5897};
5898
Fred Drake12c6e2d1999-12-14 21:25:03 +00005899static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005900conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5901 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005902{
5903 if (PyInt_Check(arg)) {
5904 *valuep = PyInt_AS_LONG(arg);
5905 return 1;
5906 }
5907 if (PyString_Check(arg)) {
5908 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005909 size_t lo = 0;
5910 size_t mid;
5911 size_t hi = tablesize;
5912 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005913 char *confname = PyString_AS_STRING(arg);
5914 while (lo < hi) {
5915 mid = (lo + hi) / 2;
5916 cmp = strcmp(confname, table[mid].name);
5917 if (cmp < 0)
5918 hi = mid;
5919 else if (cmp > 0)
5920 lo = mid + 1;
5921 else {
5922 *valuep = table[mid].value;
5923 return 1;
5924 }
5925 }
5926 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5927 }
5928 else
5929 PyErr_SetString(PyExc_TypeError,
5930 "configuration names must be strings or integers");
5931 return 0;
5932}
5933
5934
5935#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5936static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005937#ifdef _PC_ABI_AIO_XFER_MAX
5938 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5939#endif
5940#ifdef _PC_ABI_ASYNC_IO
5941 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5942#endif
Fred Drakec9680921999-12-13 16:37:25 +00005943#ifdef _PC_ASYNC_IO
5944 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5945#endif
5946#ifdef _PC_CHOWN_RESTRICTED
5947 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5948#endif
5949#ifdef _PC_FILESIZEBITS
5950 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5951#endif
5952#ifdef _PC_LAST
5953 {"PC_LAST", _PC_LAST},
5954#endif
5955#ifdef _PC_LINK_MAX
5956 {"PC_LINK_MAX", _PC_LINK_MAX},
5957#endif
5958#ifdef _PC_MAX_CANON
5959 {"PC_MAX_CANON", _PC_MAX_CANON},
5960#endif
5961#ifdef _PC_MAX_INPUT
5962 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5963#endif
5964#ifdef _PC_NAME_MAX
5965 {"PC_NAME_MAX", _PC_NAME_MAX},
5966#endif
5967#ifdef _PC_NO_TRUNC
5968 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5969#endif
5970#ifdef _PC_PATH_MAX
5971 {"PC_PATH_MAX", _PC_PATH_MAX},
5972#endif
5973#ifdef _PC_PIPE_BUF
5974 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5975#endif
5976#ifdef _PC_PRIO_IO
5977 {"PC_PRIO_IO", _PC_PRIO_IO},
5978#endif
5979#ifdef _PC_SOCK_MAXBUF
5980 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5981#endif
5982#ifdef _PC_SYNC_IO
5983 {"PC_SYNC_IO", _PC_SYNC_IO},
5984#endif
5985#ifdef _PC_VDISABLE
5986 {"PC_VDISABLE", _PC_VDISABLE},
5987#endif
5988};
5989
Fred Drakec9680921999-12-13 16:37:25 +00005990static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005991conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005992{
5993 return conv_confname(arg, valuep, posix_constants_pathconf,
5994 sizeof(posix_constants_pathconf)
5995 / sizeof(struct constdef));
5996}
5997#endif
5998
5999#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006000PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006001"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006002Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006004
6005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006006posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006007{
6008 PyObject *result = NULL;
6009 int name, fd;
6010
Fred Drake12c6e2d1999-12-14 21:25:03 +00006011 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6012 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006013 long limit;
6014
6015 errno = 0;
6016 limit = fpathconf(fd, name);
6017 if (limit == -1 && errno != 0)
6018 posix_error();
6019 else
6020 result = PyInt_FromLong(limit);
6021 }
6022 return result;
6023}
6024#endif
6025
6026
6027#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006029"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006030Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006032
6033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006034posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006035{
6036 PyObject *result = NULL;
6037 int name;
6038 char *path;
6039
6040 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6041 conv_path_confname, &name)) {
6042 long limit;
6043
6044 errno = 0;
6045 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006046 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006047 if (errno == EINVAL)
6048 /* could be a path or name problem */
6049 posix_error();
6050 else
6051 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006052 }
Fred Drakec9680921999-12-13 16:37:25 +00006053 else
6054 result = PyInt_FromLong(limit);
6055 }
6056 return result;
6057}
6058#endif
6059
6060#ifdef HAVE_CONFSTR
6061static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006062#ifdef _CS_ARCHITECTURE
6063 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6064#endif
6065#ifdef _CS_HOSTNAME
6066 {"CS_HOSTNAME", _CS_HOSTNAME},
6067#endif
6068#ifdef _CS_HW_PROVIDER
6069 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6070#endif
6071#ifdef _CS_HW_SERIAL
6072 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6073#endif
6074#ifdef _CS_INITTAB_NAME
6075 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6076#endif
Fred Drakec9680921999-12-13 16:37:25 +00006077#ifdef _CS_LFS64_CFLAGS
6078 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6079#endif
6080#ifdef _CS_LFS64_LDFLAGS
6081 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6082#endif
6083#ifdef _CS_LFS64_LIBS
6084 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6085#endif
6086#ifdef _CS_LFS64_LINTFLAGS
6087 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6088#endif
6089#ifdef _CS_LFS_CFLAGS
6090 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6091#endif
6092#ifdef _CS_LFS_LDFLAGS
6093 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6094#endif
6095#ifdef _CS_LFS_LIBS
6096 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6097#endif
6098#ifdef _CS_LFS_LINTFLAGS
6099 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6100#endif
Fred Draked86ed291999-12-15 15:34:33 +00006101#ifdef _CS_MACHINE
6102 {"CS_MACHINE", _CS_MACHINE},
6103#endif
Fred Drakec9680921999-12-13 16:37:25 +00006104#ifdef _CS_PATH
6105 {"CS_PATH", _CS_PATH},
6106#endif
Fred Draked86ed291999-12-15 15:34:33 +00006107#ifdef _CS_RELEASE
6108 {"CS_RELEASE", _CS_RELEASE},
6109#endif
6110#ifdef _CS_SRPC_DOMAIN
6111 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6112#endif
6113#ifdef _CS_SYSNAME
6114 {"CS_SYSNAME", _CS_SYSNAME},
6115#endif
6116#ifdef _CS_VERSION
6117 {"CS_VERSION", _CS_VERSION},
6118#endif
Fred Drakec9680921999-12-13 16:37:25 +00006119#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6120 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6121#endif
6122#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6123 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6124#endif
6125#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6126 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6127#endif
6128#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6129 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6130#endif
6131#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6132 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6133#endif
6134#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6135 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6136#endif
6137#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6138 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6139#endif
6140#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6141 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6142#endif
6143#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6144 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6145#endif
6146#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6147 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6148#endif
6149#ifdef _CS_XBS5_LP64_OFF64_LIBS
6150 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6151#endif
6152#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6153 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6154#endif
6155#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6156 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6157#endif
6158#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6159 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6160#endif
6161#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6162 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6163#endif
6164#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6165 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6166#endif
Fred Draked86ed291999-12-15 15:34:33 +00006167#ifdef _MIPS_CS_AVAIL_PROCESSORS
6168 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6169#endif
6170#ifdef _MIPS_CS_BASE
6171 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6172#endif
6173#ifdef _MIPS_CS_HOSTID
6174 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6175#endif
6176#ifdef _MIPS_CS_HW_NAME
6177 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6178#endif
6179#ifdef _MIPS_CS_NUM_PROCESSORS
6180 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6181#endif
6182#ifdef _MIPS_CS_OSREL_MAJ
6183 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6184#endif
6185#ifdef _MIPS_CS_OSREL_MIN
6186 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6187#endif
6188#ifdef _MIPS_CS_OSREL_PATCH
6189 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6190#endif
6191#ifdef _MIPS_CS_OS_NAME
6192 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6193#endif
6194#ifdef _MIPS_CS_OS_PROVIDER
6195 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6196#endif
6197#ifdef _MIPS_CS_PROCESSORS
6198 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6199#endif
6200#ifdef _MIPS_CS_SERIAL
6201 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6202#endif
6203#ifdef _MIPS_CS_VENDOR
6204 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6205#endif
Fred Drakec9680921999-12-13 16:37:25 +00006206};
6207
6208static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006209conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006210{
6211 return conv_confname(arg, valuep, posix_constants_confstr,
6212 sizeof(posix_constants_confstr)
6213 / sizeof(struct constdef));
6214}
6215
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006217"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006218Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006219
6220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006221posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006222{
6223 PyObject *result = NULL;
6224 int name;
6225 char buffer[64];
6226
6227 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6228 int len = confstr(name, buffer, sizeof(buffer));
6229
Fred Drakec9680921999-12-13 16:37:25 +00006230 errno = 0;
6231 if (len == 0) {
6232 if (errno != 0)
6233 posix_error();
6234 else
6235 result = PyString_FromString("");
6236 }
6237 else {
6238 if (len >= sizeof(buffer)) {
6239 result = PyString_FromStringAndSize(NULL, len);
6240 if (result != NULL)
6241 confstr(name, PyString_AS_STRING(result), len+1);
6242 }
6243 else
6244 result = PyString_FromString(buffer);
6245 }
6246 }
6247 return result;
6248}
6249#endif
6250
6251
6252#ifdef HAVE_SYSCONF
6253static struct constdef posix_constants_sysconf[] = {
6254#ifdef _SC_2_CHAR_TERM
6255 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6256#endif
6257#ifdef _SC_2_C_BIND
6258 {"SC_2_C_BIND", _SC_2_C_BIND},
6259#endif
6260#ifdef _SC_2_C_DEV
6261 {"SC_2_C_DEV", _SC_2_C_DEV},
6262#endif
6263#ifdef _SC_2_C_VERSION
6264 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6265#endif
6266#ifdef _SC_2_FORT_DEV
6267 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6268#endif
6269#ifdef _SC_2_FORT_RUN
6270 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6271#endif
6272#ifdef _SC_2_LOCALEDEF
6273 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6274#endif
6275#ifdef _SC_2_SW_DEV
6276 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6277#endif
6278#ifdef _SC_2_UPE
6279 {"SC_2_UPE", _SC_2_UPE},
6280#endif
6281#ifdef _SC_2_VERSION
6282 {"SC_2_VERSION", _SC_2_VERSION},
6283#endif
Fred Draked86ed291999-12-15 15:34:33 +00006284#ifdef _SC_ABI_ASYNCHRONOUS_IO
6285 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6286#endif
6287#ifdef _SC_ACL
6288 {"SC_ACL", _SC_ACL},
6289#endif
Fred Drakec9680921999-12-13 16:37:25 +00006290#ifdef _SC_AIO_LISTIO_MAX
6291 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6292#endif
Fred Drakec9680921999-12-13 16:37:25 +00006293#ifdef _SC_AIO_MAX
6294 {"SC_AIO_MAX", _SC_AIO_MAX},
6295#endif
6296#ifdef _SC_AIO_PRIO_DELTA_MAX
6297 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6298#endif
6299#ifdef _SC_ARG_MAX
6300 {"SC_ARG_MAX", _SC_ARG_MAX},
6301#endif
6302#ifdef _SC_ASYNCHRONOUS_IO
6303 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6304#endif
6305#ifdef _SC_ATEXIT_MAX
6306 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6307#endif
Fred Draked86ed291999-12-15 15:34:33 +00006308#ifdef _SC_AUDIT
6309 {"SC_AUDIT", _SC_AUDIT},
6310#endif
Fred Drakec9680921999-12-13 16:37:25 +00006311#ifdef _SC_AVPHYS_PAGES
6312 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6313#endif
6314#ifdef _SC_BC_BASE_MAX
6315 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6316#endif
6317#ifdef _SC_BC_DIM_MAX
6318 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6319#endif
6320#ifdef _SC_BC_SCALE_MAX
6321 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6322#endif
6323#ifdef _SC_BC_STRING_MAX
6324 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6325#endif
Fred Draked86ed291999-12-15 15:34:33 +00006326#ifdef _SC_CAP
6327 {"SC_CAP", _SC_CAP},
6328#endif
Fred Drakec9680921999-12-13 16:37:25 +00006329#ifdef _SC_CHARCLASS_NAME_MAX
6330 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6331#endif
6332#ifdef _SC_CHAR_BIT
6333 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6334#endif
6335#ifdef _SC_CHAR_MAX
6336 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6337#endif
6338#ifdef _SC_CHAR_MIN
6339 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6340#endif
6341#ifdef _SC_CHILD_MAX
6342 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6343#endif
6344#ifdef _SC_CLK_TCK
6345 {"SC_CLK_TCK", _SC_CLK_TCK},
6346#endif
6347#ifdef _SC_COHER_BLKSZ
6348 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6349#endif
6350#ifdef _SC_COLL_WEIGHTS_MAX
6351 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6352#endif
6353#ifdef _SC_DCACHE_ASSOC
6354 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6355#endif
6356#ifdef _SC_DCACHE_BLKSZ
6357 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6358#endif
6359#ifdef _SC_DCACHE_LINESZ
6360 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6361#endif
6362#ifdef _SC_DCACHE_SZ
6363 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6364#endif
6365#ifdef _SC_DCACHE_TBLKSZ
6366 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6367#endif
6368#ifdef _SC_DELAYTIMER_MAX
6369 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6370#endif
6371#ifdef _SC_EQUIV_CLASS_MAX
6372 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6373#endif
6374#ifdef _SC_EXPR_NEST_MAX
6375 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6376#endif
6377#ifdef _SC_FSYNC
6378 {"SC_FSYNC", _SC_FSYNC},
6379#endif
6380#ifdef _SC_GETGR_R_SIZE_MAX
6381 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6382#endif
6383#ifdef _SC_GETPW_R_SIZE_MAX
6384 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6385#endif
6386#ifdef _SC_ICACHE_ASSOC
6387 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6388#endif
6389#ifdef _SC_ICACHE_BLKSZ
6390 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6391#endif
6392#ifdef _SC_ICACHE_LINESZ
6393 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6394#endif
6395#ifdef _SC_ICACHE_SZ
6396 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6397#endif
Fred Draked86ed291999-12-15 15:34:33 +00006398#ifdef _SC_INF
6399 {"SC_INF", _SC_INF},
6400#endif
Fred Drakec9680921999-12-13 16:37:25 +00006401#ifdef _SC_INT_MAX
6402 {"SC_INT_MAX", _SC_INT_MAX},
6403#endif
6404#ifdef _SC_INT_MIN
6405 {"SC_INT_MIN", _SC_INT_MIN},
6406#endif
6407#ifdef _SC_IOV_MAX
6408 {"SC_IOV_MAX", _SC_IOV_MAX},
6409#endif
Fred Draked86ed291999-12-15 15:34:33 +00006410#ifdef _SC_IP_SECOPTS
6411 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6412#endif
Fred Drakec9680921999-12-13 16:37:25 +00006413#ifdef _SC_JOB_CONTROL
6414 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6415#endif
Fred Draked86ed291999-12-15 15:34:33 +00006416#ifdef _SC_KERN_POINTERS
6417 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6418#endif
6419#ifdef _SC_KERN_SIM
6420 {"SC_KERN_SIM", _SC_KERN_SIM},
6421#endif
Fred Drakec9680921999-12-13 16:37:25 +00006422#ifdef _SC_LINE_MAX
6423 {"SC_LINE_MAX", _SC_LINE_MAX},
6424#endif
6425#ifdef _SC_LOGIN_NAME_MAX
6426 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6427#endif
6428#ifdef _SC_LOGNAME_MAX
6429 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6430#endif
6431#ifdef _SC_LONG_BIT
6432 {"SC_LONG_BIT", _SC_LONG_BIT},
6433#endif
Fred Draked86ed291999-12-15 15:34:33 +00006434#ifdef _SC_MAC
6435 {"SC_MAC", _SC_MAC},
6436#endif
Fred Drakec9680921999-12-13 16:37:25 +00006437#ifdef _SC_MAPPED_FILES
6438 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6439#endif
6440#ifdef _SC_MAXPID
6441 {"SC_MAXPID", _SC_MAXPID},
6442#endif
6443#ifdef _SC_MB_LEN_MAX
6444 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6445#endif
6446#ifdef _SC_MEMLOCK
6447 {"SC_MEMLOCK", _SC_MEMLOCK},
6448#endif
6449#ifdef _SC_MEMLOCK_RANGE
6450 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6451#endif
6452#ifdef _SC_MEMORY_PROTECTION
6453 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6454#endif
6455#ifdef _SC_MESSAGE_PASSING
6456 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6457#endif
Fred Draked86ed291999-12-15 15:34:33 +00006458#ifdef _SC_MMAP_FIXED_ALIGNMENT
6459 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6460#endif
Fred Drakec9680921999-12-13 16:37:25 +00006461#ifdef _SC_MQ_OPEN_MAX
6462 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6463#endif
6464#ifdef _SC_MQ_PRIO_MAX
6465 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6466#endif
Fred Draked86ed291999-12-15 15:34:33 +00006467#ifdef _SC_NACLS_MAX
6468 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6469#endif
Fred Drakec9680921999-12-13 16:37:25 +00006470#ifdef _SC_NGROUPS_MAX
6471 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6472#endif
6473#ifdef _SC_NL_ARGMAX
6474 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6475#endif
6476#ifdef _SC_NL_LANGMAX
6477 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6478#endif
6479#ifdef _SC_NL_MSGMAX
6480 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6481#endif
6482#ifdef _SC_NL_NMAX
6483 {"SC_NL_NMAX", _SC_NL_NMAX},
6484#endif
6485#ifdef _SC_NL_SETMAX
6486 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6487#endif
6488#ifdef _SC_NL_TEXTMAX
6489 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6490#endif
6491#ifdef _SC_NPROCESSORS_CONF
6492 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6493#endif
6494#ifdef _SC_NPROCESSORS_ONLN
6495 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6496#endif
Fred Draked86ed291999-12-15 15:34:33 +00006497#ifdef _SC_NPROC_CONF
6498 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6499#endif
6500#ifdef _SC_NPROC_ONLN
6501 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6502#endif
Fred Drakec9680921999-12-13 16:37:25 +00006503#ifdef _SC_NZERO
6504 {"SC_NZERO", _SC_NZERO},
6505#endif
6506#ifdef _SC_OPEN_MAX
6507 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6508#endif
6509#ifdef _SC_PAGESIZE
6510 {"SC_PAGESIZE", _SC_PAGESIZE},
6511#endif
6512#ifdef _SC_PAGE_SIZE
6513 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6514#endif
6515#ifdef _SC_PASS_MAX
6516 {"SC_PASS_MAX", _SC_PASS_MAX},
6517#endif
6518#ifdef _SC_PHYS_PAGES
6519 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6520#endif
6521#ifdef _SC_PII
6522 {"SC_PII", _SC_PII},
6523#endif
6524#ifdef _SC_PII_INTERNET
6525 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6526#endif
6527#ifdef _SC_PII_INTERNET_DGRAM
6528 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6529#endif
6530#ifdef _SC_PII_INTERNET_STREAM
6531 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6532#endif
6533#ifdef _SC_PII_OSI
6534 {"SC_PII_OSI", _SC_PII_OSI},
6535#endif
6536#ifdef _SC_PII_OSI_CLTS
6537 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6538#endif
6539#ifdef _SC_PII_OSI_COTS
6540 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6541#endif
6542#ifdef _SC_PII_OSI_M
6543 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6544#endif
6545#ifdef _SC_PII_SOCKET
6546 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6547#endif
6548#ifdef _SC_PII_XTI
6549 {"SC_PII_XTI", _SC_PII_XTI},
6550#endif
6551#ifdef _SC_POLL
6552 {"SC_POLL", _SC_POLL},
6553#endif
6554#ifdef _SC_PRIORITIZED_IO
6555 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6556#endif
6557#ifdef _SC_PRIORITY_SCHEDULING
6558 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6559#endif
6560#ifdef _SC_REALTIME_SIGNALS
6561 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6562#endif
6563#ifdef _SC_RE_DUP_MAX
6564 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6565#endif
6566#ifdef _SC_RTSIG_MAX
6567 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6568#endif
6569#ifdef _SC_SAVED_IDS
6570 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6571#endif
6572#ifdef _SC_SCHAR_MAX
6573 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6574#endif
6575#ifdef _SC_SCHAR_MIN
6576 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6577#endif
6578#ifdef _SC_SELECT
6579 {"SC_SELECT", _SC_SELECT},
6580#endif
6581#ifdef _SC_SEMAPHORES
6582 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6583#endif
6584#ifdef _SC_SEM_NSEMS_MAX
6585 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6586#endif
6587#ifdef _SC_SEM_VALUE_MAX
6588 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6589#endif
6590#ifdef _SC_SHARED_MEMORY_OBJECTS
6591 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6592#endif
6593#ifdef _SC_SHRT_MAX
6594 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6595#endif
6596#ifdef _SC_SHRT_MIN
6597 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6598#endif
6599#ifdef _SC_SIGQUEUE_MAX
6600 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6601#endif
6602#ifdef _SC_SIGRT_MAX
6603 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6604#endif
6605#ifdef _SC_SIGRT_MIN
6606 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6607#endif
Fred Draked86ed291999-12-15 15:34:33 +00006608#ifdef _SC_SOFTPOWER
6609 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6610#endif
Fred Drakec9680921999-12-13 16:37:25 +00006611#ifdef _SC_SPLIT_CACHE
6612 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6613#endif
6614#ifdef _SC_SSIZE_MAX
6615 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6616#endif
6617#ifdef _SC_STACK_PROT
6618 {"SC_STACK_PROT", _SC_STACK_PROT},
6619#endif
6620#ifdef _SC_STREAM_MAX
6621 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6622#endif
6623#ifdef _SC_SYNCHRONIZED_IO
6624 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6625#endif
6626#ifdef _SC_THREADS
6627 {"SC_THREADS", _SC_THREADS},
6628#endif
6629#ifdef _SC_THREAD_ATTR_STACKADDR
6630 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6631#endif
6632#ifdef _SC_THREAD_ATTR_STACKSIZE
6633 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6634#endif
6635#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6636 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6637#endif
6638#ifdef _SC_THREAD_KEYS_MAX
6639 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6640#endif
6641#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6642 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6643#endif
6644#ifdef _SC_THREAD_PRIO_INHERIT
6645 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6646#endif
6647#ifdef _SC_THREAD_PRIO_PROTECT
6648 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6649#endif
6650#ifdef _SC_THREAD_PROCESS_SHARED
6651 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6652#endif
6653#ifdef _SC_THREAD_SAFE_FUNCTIONS
6654 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6655#endif
6656#ifdef _SC_THREAD_STACK_MIN
6657 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6658#endif
6659#ifdef _SC_THREAD_THREADS_MAX
6660 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6661#endif
6662#ifdef _SC_TIMERS
6663 {"SC_TIMERS", _SC_TIMERS},
6664#endif
6665#ifdef _SC_TIMER_MAX
6666 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6667#endif
6668#ifdef _SC_TTY_NAME_MAX
6669 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6670#endif
6671#ifdef _SC_TZNAME_MAX
6672 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6673#endif
6674#ifdef _SC_T_IOV_MAX
6675 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6676#endif
6677#ifdef _SC_UCHAR_MAX
6678 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6679#endif
6680#ifdef _SC_UINT_MAX
6681 {"SC_UINT_MAX", _SC_UINT_MAX},
6682#endif
6683#ifdef _SC_UIO_MAXIOV
6684 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6685#endif
6686#ifdef _SC_ULONG_MAX
6687 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6688#endif
6689#ifdef _SC_USHRT_MAX
6690 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6691#endif
6692#ifdef _SC_VERSION
6693 {"SC_VERSION", _SC_VERSION},
6694#endif
6695#ifdef _SC_WORD_BIT
6696 {"SC_WORD_BIT", _SC_WORD_BIT},
6697#endif
6698#ifdef _SC_XBS5_ILP32_OFF32
6699 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6700#endif
6701#ifdef _SC_XBS5_ILP32_OFFBIG
6702 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6703#endif
6704#ifdef _SC_XBS5_LP64_OFF64
6705 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6706#endif
6707#ifdef _SC_XBS5_LPBIG_OFFBIG
6708 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6709#endif
6710#ifdef _SC_XOPEN_CRYPT
6711 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6712#endif
6713#ifdef _SC_XOPEN_ENH_I18N
6714 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6715#endif
6716#ifdef _SC_XOPEN_LEGACY
6717 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6718#endif
6719#ifdef _SC_XOPEN_REALTIME
6720 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6721#endif
6722#ifdef _SC_XOPEN_REALTIME_THREADS
6723 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6724#endif
6725#ifdef _SC_XOPEN_SHM
6726 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6727#endif
6728#ifdef _SC_XOPEN_UNIX
6729 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6730#endif
6731#ifdef _SC_XOPEN_VERSION
6732 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6733#endif
6734#ifdef _SC_XOPEN_XCU_VERSION
6735 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6736#endif
6737#ifdef _SC_XOPEN_XPG2
6738 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6739#endif
6740#ifdef _SC_XOPEN_XPG3
6741 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6742#endif
6743#ifdef _SC_XOPEN_XPG4
6744 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6745#endif
6746};
6747
6748static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006749conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006750{
6751 return conv_confname(arg, valuep, posix_constants_sysconf,
6752 sizeof(posix_constants_sysconf)
6753 / sizeof(struct constdef));
6754}
6755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006756PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006757"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006759
6760static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006761posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006762{
6763 PyObject *result = NULL;
6764 int name;
6765
6766 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6767 int value;
6768
6769 errno = 0;
6770 value = sysconf(name);
6771 if (value == -1 && errno != 0)
6772 posix_error();
6773 else
6774 result = PyInt_FromLong(value);
6775 }
6776 return result;
6777}
6778#endif
6779
6780
Fred Drakebec628d1999-12-15 18:31:10 +00006781/* This code is used to ensure that the tables of configuration value names
6782 * are in sorted order as required by conv_confname(), and also to build the
6783 * the exported dictionaries that are used to publish information about the
6784 * names available on the host platform.
6785 *
6786 * Sorting the table at runtime ensures that the table is properly ordered
6787 * when used, even for platforms we're not able to test on. It also makes
6788 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006789 */
Fred Drakebec628d1999-12-15 18:31:10 +00006790
6791static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006792cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006793{
6794 const struct constdef *c1 =
6795 (const struct constdef *) v1;
6796 const struct constdef *c2 =
6797 (const struct constdef *) v2;
6798
6799 return strcmp(c1->name, c2->name);
6800}
6801
6802static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006803setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006804 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006805{
Fred Drakebec628d1999-12-15 18:31:10 +00006806 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006807 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006808
6809 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6810 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006811 if (d == NULL)
6812 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006813
Barry Warsaw3155db32000-04-13 15:20:40 +00006814 for (i=0; i < tablesize; ++i) {
6815 PyObject *o = PyInt_FromLong(table[i].value);
6816 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6817 Py_XDECREF(o);
6818 Py_DECREF(d);
6819 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006820 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006821 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006822 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006823 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006824}
6825
Fred Drakebec628d1999-12-15 18:31:10 +00006826/* Return -1 on failure, 0 on success. */
6827static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006828setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006829{
6830#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006831 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006832 sizeof(posix_constants_pathconf)
6833 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006834 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006835 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006836#endif
6837#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006838 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006839 sizeof(posix_constants_confstr)
6840 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006841 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006842 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006843#endif
6844#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006845 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006846 sizeof(posix_constants_sysconf)
6847 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006848 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006849 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006850#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006851 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006852}
Fred Draked86ed291999-12-15 15:34:33 +00006853
6854
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006855PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006856"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006857Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006859
6860static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006861posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006862{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006863 abort();
6864 /*NOTREACHED*/
6865 Py_FatalError("abort() called from Python code didn't abort!");
6866 return NULL;
6867}
Fred Drakebec628d1999-12-15 18:31:10 +00006868
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006869#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006870PyDoc_STRVAR(win32_startfile__doc__,
6871"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006872\n\
6873This acts like double-clicking the file in Explorer, or giving the file\n\
6874name as an argument to the DOS \"start\" command: the file is opened\n\
6875with whatever application (if any) its extension is associated.\n\
6876\n\
6877startfile returns as soon as the associated application is launched.\n\
6878There is no option to wait for the application to close, and no way\n\
6879to retrieve the application's exit status.\n\
6880\n\
6881The filepath is relative to the current directory. If you want to use\n\
6882an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006883the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006884
6885static PyObject *
6886win32_startfile(PyObject *self, PyObject *args)
6887{
6888 char *filepath;
6889 HINSTANCE rc;
6890 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6891 return NULL;
6892 Py_BEGIN_ALLOW_THREADS
6893 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6894 Py_END_ALLOW_THREADS
6895 if (rc <= (HINSTANCE)32)
6896 return win32_error("startfile", filepath);
6897 Py_INCREF(Py_None);
6898 return Py_None;
6899}
6900#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006901
Martin v. Löwis438b5342002-12-27 10:16:42 +00006902#ifdef HAVE_GETLOADAVG
6903PyDoc_STRVAR(posix_getloadavg__doc__,
6904"getloadavg() -> (float, float, float)\n\n\
6905Return the number of processes in the system run queue averaged over\n\
6906the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6907was unobtainable");
6908
6909static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006910posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006911{
6912 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006913 if (getloadavg(loadavg, 3)!=3) {
6914 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6915 return NULL;
6916 } else
6917 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
6918}
6919#endif
6920
6921
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006922static PyMethodDef posix_methods[] = {
6923 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6924#ifdef HAVE_TTYNAME
6925 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6926#endif
6927 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6928 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006929#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006930 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006931#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006932#ifdef HAVE_LCHOWN
6933 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6934#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006935#ifdef HAVE_CHROOT
6936 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6937#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006938#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00006939 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006940#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006941#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00006942 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00006943#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00006944 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006945#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00006946#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006947#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006949#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006950 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6951 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6952 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006953#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006954 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006955#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006956#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006957 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006958#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006959 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6960 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6961 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006962 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006963#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006964 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006965#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006966#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006967 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006968#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006969 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006970#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00006971 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006972#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006973 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6974 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6975 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006976#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00006977 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006978#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006979 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006980#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006981 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6982 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006983#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006984#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006985 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6986 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006987#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006988#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00006989 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006990#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006991#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00006992 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006993#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006994#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00006995 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006996#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006997#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00006998 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00006999#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007000#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007001 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007002#endif /* HAVE_GETEGID */
7003#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007004 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007005#endif /* HAVE_GETEUID */
7006#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007007 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007008#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007009#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007010 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007011#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007012 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007013#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007014 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007015#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007016#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007017 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007018#endif /* HAVE_GETPPID */
7019#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007020 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007021#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007022#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007023 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007024#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007025#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007026 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007027#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007028#ifdef HAVE_KILLPG
7029 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7030#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007031#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007032 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007033#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007034#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007035 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007036#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007037 {"popen2", win32_popen2, METH_VARARGS},
7038 {"popen3", win32_popen3, METH_VARARGS},
7039 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007040 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007041#else
7042#if defined(PYOS_OS2) && defined(PYCC_GCC)
7043 {"popen2", os2emx_popen2, METH_VARARGS},
7044 {"popen3", os2emx_popen3, METH_VARARGS},
7045 {"popen4", os2emx_popen4, METH_VARARGS},
7046#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007047#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007048#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007049#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007050 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007051#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007052#ifdef HAVE_SETEUID
7053 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7054#endif /* HAVE_SETEUID */
7055#ifdef HAVE_SETEGID
7056 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7057#endif /* HAVE_SETEGID */
7058#ifdef HAVE_SETREUID
7059 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7060#endif /* HAVE_SETREUID */
7061#ifdef HAVE_SETREGID
7062 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7063#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007064#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007065 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007066#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007067#ifdef HAVE_SETGROUPS
7068 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7069#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007070#ifdef HAVE_GETPGID
7071 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7072#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007073#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007074 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007075#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007076#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007077 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007078#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007079#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007080 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007081#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007082#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007083 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007084#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007085#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007086 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007087#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007088#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007089 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007090#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007091#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007092 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007093#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007094 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7095 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7096 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7097 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7098 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7099 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7100 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7101 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7102 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007103 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007104#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007105 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007106#endif
7107#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007108 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007109#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007110#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007111 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7112#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007113#ifdef HAVE_DEVICE_MACROS
7114 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7115 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7116 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7117#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007118#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007119 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007120#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007121#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007122 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007123#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007124#ifdef HAVE_UNSETENV
7125 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7126#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007127#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007128 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007129#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007130#ifdef HAVE_FCHDIR
7131 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7132#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007133#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007134 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007135#endif
7136#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007137 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007138#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007139#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007140#ifdef WCOREDUMP
7141 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7142#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007143#ifdef WIFCONTINUED
7144 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7145#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007146#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007147 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007148#endif /* WIFSTOPPED */
7149#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007150 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007151#endif /* WIFSIGNALED */
7152#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007153 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007154#endif /* WIFEXITED */
7155#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007156 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007157#endif /* WEXITSTATUS */
7158#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007159 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007160#endif /* WTERMSIG */
7161#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007162 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007163#endif /* WSTOPSIG */
7164#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007165#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007166 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007167#endif
7168#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007170#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007171#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007172 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007173#endif
7174#ifdef HAVE_TEMPNAM
7175 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7176#endif
7177#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007178 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007179#endif
Fred Drakec9680921999-12-13 16:37:25 +00007180#ifdef HAVE_CONFSTR
7181 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7182#endif
7183#ifdef HAVE_SYSCONF
7184 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7185#endif
7186#ifdef HAVE_FPATHCONF
7187 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7188#endif
7189#ifdef HAVE_PATHCONF
7190 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7191#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007192 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007193#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007194 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7195#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007196#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007197 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007198#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007199 {NULL, NULL} /* Sentinel */
7200};
7201
7202
Barry Warsaw4a342091996-12-19 23:50:02 +00007203static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007204ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007205{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007206 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007207}
7208
Guido van Rossumd48f2521997-12-05 22:19:34 +00007209#if defined(PYOS_OS2)
7210/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007211static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007212{
7213 APIRET rc;
7214 ULONG values[QSV_MAX+1];
7215 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007216 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007217
7218 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007219 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007220 Py_END_ALLOW_THREADS
7221
7222 if (rc != NO_ERROR) {
7223 os2_error(rc);
7224 return -1;
7225 }
7226
Fred Drake4d1e64b2002-04-15 19:40:07 +00007227 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7228 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7229 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7230 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7231 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7232 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7233 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007234
7235 switch (values[QSV_VERSION_MINOR]) {
7236 case 0: ver = "2.00"; break;
7237 case 10: ver = "2.10"; break;
7238 case 11: ver = "2.11"; break;
7239 case 30: ver = "3.00"; break;
7240 case 40: ver = "4.00"; break;
7241 case 50: ver = "5.00"; break;
7242 default:
Tim Peters885d4572001-11-28 20:27:42 +00007243 PyOS_snprintf(tmp, sizeof(tmp),
7244 "%d-%d", values[QSV_VERSION_MAJOR],
7245 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007246 ver = &tmp[0];
7247 }
7248
7249 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007250 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007251 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007252
7253 /* Add Indicator of Which Drive was Used to Boot the System */
7254 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7255 tmp[1] = ':';
7256 tmp[2] = '\0';
7257
Fred Drake4d1e64b2002-04-15 19:40:07 +00007258 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007259}
7260#endif
7261
Barry Warsaw4a342091996-12-19 23:50:02 +00007262static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007263all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007264{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007265#ifdef F_OK
7266 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007267#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007268#ifdef R_OK
7269 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007270#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007271#ifdef W_OK
7272 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007273#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007274#ifdef X_OK
7275 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007276#endif
Fred Drakec9680921999-12-13 16:37:25 +00007277#ifdef NGROUPS_MAX
7278 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7279#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007280#ifdef TMP_MAX
7281 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7282#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007283#ifdef WCONTINUED
7284 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7285#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007286#ifdef WNOHANG
7287 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007288#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007289#ifdef WUNTRACED
7290 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7291#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007292#ifdef O_RDONLY
7293 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7294#endif
7295#ifdef O_WRONLY
7296 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7297#endif
7298#ifdef O_RDWR
7299 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7300#endif
7301#ifdef O_NDELAY
7302 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7303#endif
7304#ifdef O_NONBLOCK
7305 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7306#endif
7307#ifdef O_APPEND
7308 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7309#endif
7310#ifdef O_DSYNC
7311 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7312#endif
7313#ifdef O_RSYNC
7314 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7315#endif
7316#ifdef O_SYNC
7317 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7318#endif
7319#ifdef O_NOCTTY
7320 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7321#endif
7322#ifdef O_CREAT
7323 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7324#endif
7325#ifdef O_EXCL
7326 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7327#endif
7328#ifdef O_TRUNC
7329 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7330#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007331#ifdef O_BINARY
7332 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7333#endif
7334#ifdef O_TEXT
7335 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7336#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007337#ifdef O_LARGEFILE
7338 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7339#endif
7340
Tim Peters5aa91602002-01-30 05:46:57 +00007341/* MS Windows */
7342#ifdef O_NOINHERIT
7343 /* Don't inherit in child processes. */
7344 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7345#endif
7346#ifdef _O_SHORT_LIVED
7347 /* Optimize for short life (keep in memory). */
7348 /* MS forgot to define this one with a non-underscore form too. */
7349 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7350#endif
7351#ifdef O_TEMPORARY
7352 /* Automatically delete when last handle is closed. */
7353 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7354#endif
7355#ifdef O_RANDOM
7356 /* Optimize for random access. */
7357 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7358#endif
7359#ifdef O_SEQUENTIAL
7360 /* Optimize for sequential access. */
7361 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7362#endif
7363
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007364/* GNU extensions. */
7365#ifdef O_DIRECT
7366 /* Direct disk access. */
7367 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7368#endif
7369#ifdef O_DIRECTORY
7370 /* Must be a directory. */
7371 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7372#endif
7373#ifdef O_NOFOLLOW
7374 /* Do not follow links. */
7375 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7376#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007377
Barry Warsaw5676bd12003-01-07 20:57:09 +00007378 /* These come from sysexits.h */
7379#ifdef EX_OK
7380 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007381#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007382#ifdef EX_USAGE
7383 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007384#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007385#ifdef EX_DATAERR
7386 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007387#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007388#ifdef EX_NOINPUT
7389 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007390#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007391#ifdef EX_NOUSER
7392 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007393#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007394#ifdef EX_NOHOST
7395 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007396#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007397#ifdef EX_UNAVAILABLE
7398 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007399#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007400#ifdef EX_SOFTWARE
7401 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007402#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007403#ifdef EX_OSERR
7404 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007405#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007406#ifdef EX_OSFILE
7407 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007408#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007409#ifdef EX_CANTCREAT
7410 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007411#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007412#ifdef EX_IOERR
7413 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007414#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007415#ifdef EX_TEMPFAIL
7416 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007417#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007418#ifdef EX_PROTOCOL
7419 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007420#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007421#ifdef EX_NOPERM
7422 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007423#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007424#ifdef EX_CONFIG
7425 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007426#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007427#ifdef EX_NOTFOUND
7428 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007429#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007430
Guido van Rossum246bc171999-02-01 23:54:31 +00007431#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007432#if defined(PYOS_OS2) && defined(PYCC_GCC)
7433 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7434 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7435 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7436 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7437 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7438 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7439 if (ins(d, "P_PM", (long)P_PM)) return -1;
7440 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7441 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7442 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7443 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7444 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7445 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7446 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7447 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7448 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7449 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7450 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7451 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7452 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7453#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007454 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7455 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7456 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7457 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7458 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007459#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007460#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007461
Guido van Rossumd48f2521997-12-05 22:19:34 +00007462#if defined(PYOS_OS2)
7463 if (insertvalues(d)) return -1;
7464#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007465 return 0;
7466}
7467
7468
Tim Peters5aa91602002-01-30 05:46:57 +00007469#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007470#define INITFUNC initnt
7471#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007472
7473#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007474#define INITFUNC initos2
7475#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007476
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007477#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007478#define INITFUNC initposix
7479#define MODNAME "posix"
7480#endif
7481
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007482PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007483INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007484{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007485 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007486
Fred Drake4d1e64b2002-04-15 19:40:07 +00007487 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007488 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007489 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007490
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007491 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007492 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007493 Py_XINCREF(v);
7494 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007495 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007496 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007497
Fred Drake4d1e64b2002-04-15 19:40:07 +00007498 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007499 return;
7500
Fred Drake4d1e64b2002-04-15 19:40:07 +00007501 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007502 return;
7503
Fred Drake4d1e64b2002-04-15 19:40:07 +00007504 Py_INCREF(PyExc_OSError);
7505 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007506
Guido van Rossumb3d39562000-01-31 18:41:26 +00007507#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007508 if (posix_putenv_garbage == NULL)
7509 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007510#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007511
Guido van Rossum14648392001-12-08 18:02:58 +00007512 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007513 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7514 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7515 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007516 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007517 structseq_new = StatResultType.tp_new;
7518 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007519 Py_INCREF((PyObject*) &StatResultType);
7520 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007521
Guido van Rossum14648392001-12-08 18:02:58 +00007522 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007523 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007524 Py_INCREF((PyObject*) &StatVFSResultType);
7525 PyModule_AddObject(m, "statvfs_result",
7526 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007527}