blob: bd5c32ad4e37df76909c9c92d6174696605f2cc3 [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)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000020# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#endif /* defined(__VMS) */
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000024"This module provides access to operating system functionality that is\n\
25standardized by the C Standard and the POSIX standard (a thinly\n\
26disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000029#ifndef Py_USING_UNICODE
30/* This is used in signatures of functions. */
31#define Py_UNICODE void
32#endif
33
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000034#if defined(PYOS_OS2)
35#define INCL_DOS
36#define INCL_DOSERRORS
37#define INCL_DOSPROCESS
38#define INCL_NOPMAPI
39#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000040#if defined(PYCC_GCC)
41#include <ctype.h>
42#include <io.h>
43#include <stdio.h>
44#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000045#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000046#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#endif
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049#include <sys/types.h>
50#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000051
Guido van Rossum36bc6801995-06-14 22:54:23 +000052#ifdef HAVE_SYS_WAIT_H
53#include <sys/wait.h> /* For WNOHANG */
54#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma376cc51996-12-05 23:43:35 +000056#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000057
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_FCNTL_H
59#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062#ifdef HAVE_GRP_H
63#include <grp.h>
64#endif
65
Barry Warsaw5676bd12003-01-07 20:57:09 +000066#ifdef HAVE_SYSEXITS_H
67#include <sysexits.h>
68#endif /* HAVE_SYSEXITS_H */
69
Anthony Baxter8a560de2004-10-13 15:30:56 +000070#ifdef HAVE_SYS_LOADAVG_H
71#include <sys/loadavg.h>
72#endif
73
Guido van Rossuma4916fa1996-05-23 22:58:55 +000074/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000075/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000076#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000077#include <process.h>
78#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000079#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000080#define HAVE_GETCWD 1
81#define HAVE_OPENDIR 1
82#define HAVE_SYSTEM 1
83#if defined(__OS2__)
84#define HAVE_EXECV 1
85#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000086#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#include <process.h>
88#else
89#ifdef __BORLANDC__ /* Borland compiler */
90#define HAVE_EXECV 1
91#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#define HAVE_OPENDIR 1
93#define HAVE_PIPE 1
94#define HAVE_POPEN 1
95#define HAVE_SYSTEM 1
96#define HAVE_WAIT 1
97#else
98#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000099#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000100#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_EXECV 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000105#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000106#define HAVE_FSYNC 1
107#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000108#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000109#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#else /* all other compilers */
112/* Unix functions that the configure script doesn't check for */
113#define HAVE_EXECV 1
114#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000115#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
116#define HAVE_FORK1 1
117#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_GETCWD 1
119#define HAVE_GETEGID 1
120#define HAVE_GETEUID 1
121#define HAVE_GETGID 1
122#define HAVE_GETPPID 1
123#define HAVE_GETUID 1
124#define HAVE_KILL 1
125#define HAVE_OPENDIR 1
126#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000127#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000129#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_SYSTEM 1
131#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000132#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000133#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#endif /* _MSC_VER */
135#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000137#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000138
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000140
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000141#if defined(__sgi)&&_COMPILER_VERSION>=700
142/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
143 (default) */
144extern char *ctermid_r(char *);
145#endif
146
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000147#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000151#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#endif
157#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chdir(char *);
159extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000160#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000161extern int chdir(const char *);
162extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000164#ifdef __BORLANDC__
165extern int chmod(const char *, int);
166#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000168#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int chown(const char *, uid_t, gid_t);
170extern char *getcwd(char *, int);
171extern char *strerror(int);
172extern int link(const char *, const char *);
173extern int rename(const char *, const char *);
174extern int stat(const char *, struct stat *);
175extern int unlink(const char *);
176extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000179#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_UTIME_H
188#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000191#ifdef HAVE_SYS_UTIME_H
192#include <sys/utime.h>
193#define HAVE_UTIME_H /* pretend we do for the rest of this file */
194#endif /* HAVE_SYS_UTIME_H */
195
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef HAVE_SYS_TIMES_H
197#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000198#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199
200#ifdef HAVE_SYS_PARAM_H
201#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000202#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203
204#ifdef HAVE_SYS_UTSNAME_H
205#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#define NAMLEN(dirent) strlen((dirent)->d_name)
211#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000212#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#include <direct.h>
214#define NAMLEN(dirent) strlen((dirent)->d_name)
215#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#endif
222#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000224#endif
225#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#endif
228#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#include <direct.h>
232#include <io.h>
233#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000234#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000235#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000237#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000239#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241
Guido van Rossumd48f2521997-12-05 22:19:34 +0000242#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Tim Petersbc2e10e2002-03-03 23:17:02 +0000246#ifndef MAXPATHLEN
247#define MAXPATHLEN 1024
248#endif /* MAXPATHLEN */
249
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000250#ifdef UNION_WAIT
251/* Emulate some macros on systems that have a union instead of macros */
252
253#ifndef WIFEXITED
254#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255#endif
256
257#ifndef WEXITSTATUS
258#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259#endif
260
261#ifndef WTERMSIG
262#define WTERMSIG(u_wait) ((u_wait).w_termsig)
263#endif
264
265#endif /* UNION_WAIT */
266
Greg Wardb48bc172000-03-01 21:51:56 +0000267/* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270#define USE_CTERMID_R
271#endif
272
273#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274#define USE_TMPNAM_R
275#endif
276
Fred Drake699f3522000-06-29 21:12:41 +0000277/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000278#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000279#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000280# define STAT win32_stat
281# define FSTAT win32_fstat
282# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000283#else
284# define STAT stat
285# define FSTAT fstat
286# define STRUCT_STAT struct stat
287#endif
288
Tim Peters11b23062003-04-23 02:39:17 +0000289#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000290#include <sys/mkdev.h>
291#else
292#if defined(MAJOR_IN_SYSMACROS)
293#include <sys/sysmacros.h>
294#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000295#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296#include <sys/mkdev.h>
297#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000298#endif
Fred Drake699f3522000-06-29 21:12:41 +0000299
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000301#ifdef WITH_NEXT_FRAMEWORK
302/* On Darwin/MacOSX a shared library or framework has no access to
303** environ directly, we must obtain it with _NSGetEnviron().
304*/
305#include <crt_externs.h>
306static char **environ;
307#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000309#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310
Barry Warsaw53699e91996-12-10 23:23:01 +0000311static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000312convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313{
Barry Warsaw53699e91996-12-10 23:23:01 +0000314 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 if (d == NULL)
318 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000319#ifdef WITH_NEXT_FRAMEWORK
320 if (environ == NULL)
321 environ = *_NSGetEnviron();
322#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 if (environ == NULL)
324 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000325 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000328 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 char *p = strchr(*e, '=');
330 if (p == NULL)
331 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000332 k = PyString_FromStringAndSize(*e, (int)(p-*e));
333 if (k == NULL) {
334 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000336 }
337 v = PyString_FromString(p+1);
338 if (v == NULL) {
339 PyErr_Clear();
340 Py_DECREF(k);
341 continue;
342 }
343 if (PyDict_GetItem(d, k) == NULL) {
344 if (PyDict_SetItem(d, k, v) != 0)
345 PyErr_Clear();
346 }
347 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000350#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000351 {
352 APIRET rc;
353 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
354
355 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357 PyObject *v = PyString_FromString(buffer);
358 PyDict_SetItemString(d, "BEGINLIBPATH", v);
359 Py_DECREF(v);
360 }
361 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
362 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "ENDLIBPATH", v);
365 Py_DECREF(v);
366 }
367 }
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 return d;
370}
371
372
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373/* Set a POSIX-specific error from errno, and return NULL */
374
Barry Warsawd58d7641998-07-23 16:14:40 +0000375static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000376posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000377{
Barry Warsawca74da41999-02-09 19:31:45 +0000378 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379}
Barry Warsawd58d7641998-07-23 16:14:40 +0000380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000381posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000382{
Barry Warsawca74da41999-02-09 19:31:45 +0000383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000384}
385
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000386#ifdef Py_WIN_WIDE_FILENAMES
387static PyObject *
388posix_error_with_unicode_filename(Py_UNICODE* name)
389{
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
391}
392#endif /* Py_WIN_WIDE_FILENAMES */
393
394
Mark Hammondef8b6542001-05-13 08:04:26 +0000395static PyObject *
396posix_error_with_allocated_filename(char* name)
397{
398 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
399 PyMem_Free(name);
400 return rc;
401}
402
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000403#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000404static PyObject *
405win32_error(char* function, char* filename)
406{
Mark Hammond33a6da92000-08-15 00:46:38 +0000407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000409 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000410 Windows error object, which is non-trivial.
411 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000412 errno = GetLastError();
413 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000415 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000417}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000418
419#ifdef Py_WIN_WIDE_FILENAMES
420static PyObject *
421win32_error_unicode(char* function, Py_UNICODE* filename)
422{
423 /* XXX - see win32_error for comments on 'function' */
424 errno = GetLastError();
425 if (filename)
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
427 else
428 return PyErr_SetFromWindowsErr(errno);
429}
430
431static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
432{
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj)) {
436 Py_INCREF(obj);
437 return obj;
438 }
439 if (PyUnicode_Check(obj)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
443 PyUnicode_GET_SIZE(obj));
444 }
Tim Peters11b23062003-04-23 02:39:17 +0000445 return PyUnicode_FromEncodedObject(obj,
446 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000447 "strict");
448}
449
450#endif /* Py_WIN_WIDE_FILENAMES */
451
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000452#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453
Guido van Rossumd48f2521997-12-05 22:19:34 +0000454#if defined(PYOS_OS2)
455/**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
458 static void
459os2_formatmsg(char *msgbuf, int msglen, char *reason)
460{
461 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
462
463 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
465
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000466 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000467 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
468 }
469
470 /* Add Optional Reason Text */
471 if (reason) {
472 strcat(msgbuf, " : ");
473 strcat(msgbuf, reason);
474 }
475}
476
477/**********************************************************************
478 * Decode an OS/2 Operating System Error Code
479 *
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
482 *
483 * Notes:
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
486 *
487 **********************************************************************/
488 static char *
489os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
490{
491 APIRET rc;
492 ULONG msglen;
493
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
497 errorcode, "oso001.msg", &msglen);
498 Py_END_ALLOW_THREADS
499
500 if (rc == NO_ERROR)
501 os2_formatmsg(msgbuf, msglen, reason);
502 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000503 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000504 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000505
506 return msgbuf;
507}
508
509/* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
512
513static PyObject * os2_error(int code)
514{
515 char text[1024];
516 PyObject *v;
517
518 os2_strerror(text, sizeof(text), code, "");
519
520 v = Py_BuildValue("(is)", code, text);
521 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000522 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000523 Py_DECREF(v);
524 }
525 return NULL; /* Signal to Python that an Exception is Pending */
526}
527
528#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529
530/* POSIX generic methods */
531
Barry Warsaw53699e91996-12-10 23:23:01 +0000532static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000533posix_fildes(PyObject *fdobj, int (*func)(int))
534{
535 int fd;
536 int res;
537 fd = PyObject_AsFileDescriptor(fdobj);
538 if (fd < 0)
539 return NULL;
540 Py_BEGIN_ALLOW_THREADS
541 res = (*func)(fd);
542 Py_END_ALLOW_THREADS
543 if (res < 0)
544 return posix_error();
545 Py_INCREF(Py_None);
546 return Py_None;
547}
Guido van Rossum21142a01999-01-08 21:05:37 +0000548
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000550static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551unicode_file_names(void)
552{
553 static int canusewide = -1;
554 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000555 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000556 the Windows NT family. */
557 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
558 }
559 return canusewide;
560}
561#endif
Tim Peters11b23062003-04-23 02:39:17 +0000562
Guido van Rossum21142a01999-01-08 21:05:37 +0000563static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564posix_1str(PyObject *args, char *format, int (*func)(const char*),
565 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000566{
Mark Hammondef8b6542001-05-13 08:04:26 +0000567 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000568 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000569#ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
571 PyUnicodeObject *po;
572 if (PyArg_ParseTuple(args, wformat, &po)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
577 Py_END_ALLOW_THREADS
578 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000580 Py_INCREF(Py_None);
581 return Py_None;
582 }
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
585 PyErr_Clear();
586 }
587#else
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat==NULL && wfunc == NULL);
591#endif
592
Tim Peters5aa91602002-01-30 05:46:57 +0000593 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000594 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000596 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000597 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000599 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000600 return posix_error_with_allocated_filename(path1);
601 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000602 Py_INCREF(Py_None);
603 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604}
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000607posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608 char *format,
609 int (*func)(const char *, const char *),
610 char *wformat,
611 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612{
Mark Hammondef8b6542001-05-13 08:04:26 +0000613 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000614 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000615#ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
617 PyObject *po1;
618 PyObject *po2;
619 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
620 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
621 PyObject *wpath1;
622 PyObject *wpath2;
623 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
624 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
625 if (!wpath1 || !wpath2) {
626 Py_XDECREF(wpath1);
627 Py_XDECREF(wpath2);
628 return NULL;
629 }
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
634 PyUnicode_AS_UNICODE(wpath2));
635 Py_END_ALLOW_THREADS
636 Py_XDECREF(wpath1);
637 Py_XDECREF(wpath2);
638 if (res != 0)
639 return posix_error();
640 Py_INCREF(Py_None);
641 return Py_None;
642 }
643 /* Else flow through as neither is Unicode. */
644 }
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
647 PyErr_Clear();
648 }
649#else
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat==NULL && wfunc == NULL);
653#endif
654
Mark Hammondef8b6542001-05-13 08:04:26 +0000655 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000656 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000657 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000659 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000661 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000662 PyMem_Free(path1);
663 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000664 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000665 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_INCREF(Py_None);
668 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669}
670
Martin v. Löwis14694662006-02-03 12:54:16 +0000671#ifdef MS_WINDOWS
672/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
673 - time stamps are restricted to second resolution
674 - file modification times suffer from forth-and-back conversions between
675 UTC and local time
676 Therefore, we implement our own stat, based on the Win32 API directly.
677*/
678#define HAVE_STAT_NSEC 1
679
680struct win32_stat{
681 int st_dev;
682 __int64 st_ino;
683 unsigned short st_mode;
684 int st_nlink;
685 int st_uid;
686 int st_gid;
687 int st_rdev;
688 __int64 st_size;
689 int st_atime;
690 int st_atime_nsec;
691 int st_mtime;
692 int st_mtime_nsec;
693 int st_ctime;
694 int st_ctime_nsec;
695};
696
697static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
698
699static void
700FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
701{
702 /* XXX endianness */
703 __int64 in = *(__int64*)in_ptr;
704 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
705 /* XXX Win32 supports time stamps past 2038; we currently don't */
706 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
707}
708
709/* Below, we *know* that ugo+r is 0444 */
710#if _S_IREAD != 0400
711#error Unsupported C library
712#endif
713static int
714attributes_to_mode(DWORD attr)
715{
716 int m = 0;
717 if (attr & FILE_ATTRIBUTE_DIRECTORY)
718 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
719 else
720 m |= _S_IFREG;
721 if (attr & FILE_ATTRIBUTE_READONLY)
722 m |= 0444;
723 else
724 m |= 0666;
725 return m;
726}
727
728static int
729attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
730{
731 memset(result, 0, sizeof(*result));
732 result->st_mode = attributes_to_mode(info->dwFileAttributes);
733 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
734 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
735 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
736 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
737
738 return 0;
739}
740
741static int
742win32_stat(const char* path, struct win32_stat *result)
743{
744 WIN32_FILE_ATTRIBUTE_DATA info;
745 int code;
746 char *dot;
747 /* XXX not supported on Win95 and NT 3.x */
748 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
749 /* Protocol violation: we explicitly clear errno, instead of
750 setting it to a POSIX error. Callers should use GetLastError. */
751 errno = 0;
752 return -1;
753 }
754 code = attribute_data_to_stat(&info, result);
755 if (code != 0)
756 return code;
757 /* Set S_IFEXEC if it is an .exe, .bat, ... */
758 dot = strrchr(path, '.');
759 if (dot) {
760 if (stricmp(dot, ".bat") == 0 ||
761 stricmp(dot, ".cmd") == 0 ||
762 stricmp(dot, ".exe") == 0 ||
763 stricmp(dot, ".com") == 0)
764 result->st_mode |= 0111;
765 }
766 return code;
767}
768
769static int
770win32_wstat(const wchar_t* path, struct win32_stat *result)
771{
772 int code;
773 const wchar_t *dot;
774 WIN32_FILE_ATTRIBUTE_DATA info;
775 /* XXX not supported on Win95 and NT 3.x */
776 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
777 /* Protocol violation: we explicitly clear errno, instead of
778 setting it to a POSIX error. Callers should use GetLastError. */
779 errno = 0;
780 return -1;
781 }
782 code = attribute_data_to_stat(&info, result);
783 if (code < 0)
784 return code;
785 /* Set IFEXEC if it is an .exe, .bat, ... */
786 dot = wcsrchr(path, '.');
787 if (dot) {
788 if (_wcsicmp(dot, L".bat") == 0 ||
789 _wcsicmp(dot, L".cmd") == 0 ||
790 _wcsicmp(dot, L".exe") == 0 ||
791 _wcsicmp(dot, L".com") == 0)
792 result->st_mode |= 0111;
793 }
794 return code;
795}
796
797static int
798win32_fstat(int file_number, struct win32_stat *result)
799{
800 BY_HANDLE_FILE_INFORMATION info;
801 HANDLE h;
802 int type;
803
804 h = (HANDLE)_get_osfhandle(file_number);
805
806 /* Protocol violation: we explicitly clear errno, instead of
807 setting it to a POSIX error. Callers should use GetLastError. */
808 errno = 0;
809
810 if (h == INVALID_HANDLE_VALUE) {
811 /* This is really a C library error (invalid file handle).
812 We set the Win32 error to the closes one matching. */
813 SetLastError(ERROR_INVALID_HANDLE);
814 return -1;
815 }
816 memset(result, 0, sizeof(*result));
817
818 type = GetFileType(h);
819 if (type == FILE_TYPE_UNKNOWN) {
820 DWORD error = GetLastError();
821 if (error != 0) {
822 return -1;
823 }
824 /* else: valid but unknown file */
825 }
826
827 if (type != FILE_TYPE_DISK) {
828 if (type == FILE_TYPE_CHAR)
829 result->st_mode = _S_IFCHR;
830 else if (type == FILE_TYPE_PIPE)
831 result->st_mode = _S_IFIFO;
832 return 0;
833 }
834
835 if (!GetFileInformationByHandle(h, &info)) {
836 return -1;
837 }
838
839 /* similar to stat() */
840 result->st_mode = attributes_to_mode(info.dwFileAttributes);
841 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
842 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
843 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
844 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
845 /* specific to fstat() */
846 result->st_nlink = info.nNumberOfLinks;
847 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
848 return 0;
849}
850
851#endif /* MS_WINDOWS */
852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000853PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000854"stat_result: Result from stat or lstat.\n\n\
855This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000856 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000857or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
858\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000859Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
860or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000861\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000862See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000863
864static PyStructSequence_Field stat_result_fields[] = {
865 {"st_mode", "protection bits"},
866 {"st_ino", "inode"},
867 {"st_dev", "device"},
868 {"st_nlink", "number of hard links"},
869 {"st_uid", "user ID of owner"},
870 {"st_gid", "group ID of owner"},
871 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000872 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
873 {NULL, "integer time of last access"},
874 {NULL, "integer time of last modification"},
875 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000876 {"st_atime", "time of last access"},
877 {"st_mtime", "time of last modification"},
878 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000879#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000880 {"st_blksize", "blocksize for filesystem I/O"},
881#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000882#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883 {"st_blocks", "number of blocks allocated"},
884#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000885#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000886 {"st_rdev", "device type (if inode device)"},
887#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000888#ifdef HAVE_STRUCT_STAT_ST_FLAGS
889 {"st_flags", "user defined flags for file"},
890#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000891#ifdef HAVE_STRUCT_STAT_ST_GEN
892 {"st_gen", "generation number"},
893#endif
894#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
895 {"st_birthtime", "time of creation"},
896#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000897 {0}
898};
899
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000900#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000901#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000902#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000903#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000904#endif
905
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000906#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000907#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
908#else
909#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
910#endif
911
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000912#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000913#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
914#else
915#define ST_RDEV_IDX ST_BLOCKS_IDX
916#endif
917
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000918#ifdef HAVE_STRUCT_STAT_ST_FLAGS
919#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
920#else
921#define ST_FLAGS_IDX ST_RDEV_IDX
922#endif
923
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000924#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000925#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000926#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000927#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000928#endif
929
930#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
931#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
932#else
933#define ST_BIRTHTIME_IDX ST_GEN_IDX
934#endif
935
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000936static PyStructSequence_Desc stat_result_desc = {
937 "stat_result", /* name */
938 stat_result__doc__, /* doc */
939 stat_result_fields,
940 10
941};
942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000943PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944"statvfs_result: Result from statvfs or fstatvfs.\n\n\
945This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000946 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000947or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000948\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000949See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950
951static PyStructSequence_Field statvfs_result_fields[] = {
952 {"f_bsize", },
953 {"f_frsize", },
954 {"f_blocks", },
955 {"f_bfree", },
956 {"f_bavail", },
957 {"f_files", },
958 {"f_ffree", },
959 {"f_favail", },
960 {"f_flag", },
961 {"f_namemax",},
962 {0}
963};
964
965static PyStructSequence_Desc statvfs_result_desc = {
966 "statvfs_result", /* name */
967 statvfs_result__doc__, /* doc */
968 statvfs_result_fields,
969 10
970};
971
972static PyTypeObject StatResultType;
973static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000974static newfunc structseq_new;
975
976static PyObject *
977statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
978{
979 PyStructSequence *result;
980 int i;
981
982 result = (PyStructSequence*)structseq_new(type, args, kwds);
983 if (!result)
984 return NULL;
985 /* If we have been initialized from a tuple,
986 st_?time might be set to None. Initialize it
987 from the int slots. */
988 for (i = 7; i <= 9; i++) {
989 if (result->ob_item[i+3] == Py_None) {
990 Py_DECREF(Py_None);
991 Py_INCREF(result->ob_item[i]);
992 result->ob_item[i+3] = result->ob_item[i];
993 }
994 }
995 return (PyObject*)result;
996}
997
998
999
1000/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001001static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001002
1003PyDoc_STRVAR(stat_float_times__doc__,
1004"stat_float_times([newval]) -> oldval\n\n\
1005Determine whether os.[lf]stat represents time stamps as float objects.\n\
1006If newval is True, future calls to stat() return floats, if it is False,\n\
1007future calls return ints. \n\
1008If newval is omitted, return the current setting.\n");
1009
1010static PyObject*
1011stat_float_times(PyObject* self, PyObject *args)
1012{
1013 int newval = -1;
1014 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1015 return NULL;
1016 if (newval == -1)
1017 /* Return old value */
1018 return PyBool_FromLong(_stat_float_times);
1019 _stat_float_times = newval;
1020 Py_INCREF(Py_None);
1021 return Py_None;
1022}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001023
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001024static void
1025fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1026{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001027 PyObject *fval,*ival;
1028#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001029 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001030#else
1031 ival = PyInt_FromLong((long)sec);
1032#endif
1033 if (_stat_float_times) {
1034 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1035 } else {
1036 fval = ival;
1037 Py_INCREF(fval);
1038 }
1039 PyStructSequence_SET_ITEM(v, index, ival);
1040 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001041}
1042
Tim Peters5aa91602002-01-30 05:46:57 +00001043/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001044 (used by posix_stat() and posix_fstat()) */
1045static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001046_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001047{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001048 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001049 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001050 if (v == NULL)
1051 return NULL;
1052
Martin v. Löwis14694662006-02-03 12:54:16 +00001053 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001054#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001055 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001056 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001057#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001058 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001059#endif
1060#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001061 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001062 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001063#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001064 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001065#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001066 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1067 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1068 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001069#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001070 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001071 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001072#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001073 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001074#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001075
Martin v. Löwis14694662006-02-03 12:54:16 +00001076#if defined(HAVE_STAT_TV_NSEC)
1077 ansec = st->st_atim.tv_nsec;
1078 mnsec = st->st_mtim.tv_nsec;
1079 cnsec = st->st_ctim.tv_nsec;
1080#elif defined(HAVE_STAT_TV_NSEC2)
1081 ansec = st->st_atimespec.tv_nsec;
1082 mnsec = st->st_mtimespec.tv_nsec;
1083 cnsec = st->st_ctimespec.tv_nsec;
1084#elif defined(HAVE_STAT_NSEC)
1085 ansec = st->st_atime_nsec;
1086 mnsec = st->st_mtime_nsec;
1087 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001088#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001089 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001090#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001091 fill_time(v, 7, st->st_atime, ansec);
1092 fill_time(v, 8, st->st_mtime, mnsec);
1093 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001094
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001095#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001096 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001097 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001099#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001100 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001101 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001103#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001104 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001105 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001106#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001107#ifdef HAVE_STRUCT_STAT_ST_GEN
1108 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001109 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001110#endif
1111#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1112 {
1113 PyObject *val;
1114 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001115 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001116#ifdef HAVE_STAT_TV_NSEC2
Martin v. Löwis14694662006-02-03 12:54:16 +00001117 bnsec = st.st_birthtimespec->tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#else
1119 bnsec = 0;
1120#endif
1121 if (_stat_float_times) {
1122 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1123 } else {
1124 val = PyInt_FromLong((long)bsec);
1125 }
1126 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1127 val);
1128 }
1129#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001130#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1131 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001132 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001133#endif
Fred Drake699f3522000-06-29 21:12:41 +00001134
1135 if (PyErr_Occurred()) {
1136 Py_DECREF(v);
1137 return NULL;
1138 }
1139
1140 return v;
1141}
1142
Martin v. Löwisd8948722004-06-02 09:57:56 +00001143#ifdef MS_WINDOWS
1144
1145/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1146 where / can be used in place of \ and the trailing slash is optional.
1147 Both SERVER and SHARE must have at least one character.
1148*/
1149
1150#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1151#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1152#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1153
Tim Peters4ad82172004-08-30 17:02:04 +00001154static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001155IsUNCRootA(char *path, int pathlen)
1156{
1157 #define ISSLASH ISSLASHA
1158
1159 int i, share;
1160
1161 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1162 /* minimum UNCRoot is \\x\y */
1163 return FALSE;
1164 for (i = 2; i < pathlen ; i++)
1165 if (ISSLASH(path[i])) break;
1166 if (i == 2 || i == pathlen)
1167 /* do not allow \\\SHARE or \\SERVER */
1168 return FALSE;
1169 share = i+1;
1170 for (i = share; i < pathlen; i++)
1171 if (ISSLASH(path[i])) break;
1172 return (i != share && (i == pathlen || i == pathlen-1));
1173
1174 #undef ISSLASH
1175}
1176
1177#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001178static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001179IsUNCRootW(Py_UNICODE *path, int pathlen)
1180{
1181 #define ISSLASH ISSLASHW
1182
1183 int i, share;
1184
1185 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1186 /* minimum UNCRoot is \\x\y */
1187 return FALSE;
1188 for (i = 2; i < pathlen ; i++)
1189 if (ISSLASH(path[i])) break;
1190 if (i == 2 || i == pathlen)
1191 /* do not allow \\\SHARE or \\SERVER */
1192 return FALSE;
1193 share = i+1;
1194 for (i = share; i < pathlen; i++)
1195 if (ISSLASH(path[i])) break;
1196 return (i != share && (i == pathlen || i == pathlen-1));
1197
1198 #undef ISSLASH
1199}
1200#endif /* Py_WIN_WIDE_FILENAMES */
1201#endif /* MS_WINDOWS */
1202
Barry Warsaw53699e91996-12-10 23:23:01 +00001203static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001204posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001205 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001206#ifdef __VMS
1207 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1208#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001209 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001210#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001211 char *wformat,
1212 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213{
Fred Drake699f3522000-06-29 21:12:41 +00001214 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001215 char *path = NULL; /* pass this to stat; do not free() it */
1216 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001217 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001218 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001219
1220#ifdef Py_WIN_WIDE_FILENAMES
1221 /* If on wide-character-capable OS see if argument
1222 is Unicode and if so use wide API. */
1223 if (unicode_file_names()) {
1224 PyUnicodeObject *po;
1225 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001226 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1227
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001228 Py_BEGIN_ALLOW_THREADS
1229 /* PyUnicode_AS_UNICODE result OK without
1230 thread lock as it is a simple dereference. */
1231 res = wstatfunc(wpath, &st);
1232 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001233
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001234 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001235 return win32_error_unicode("stat", wpath);
1236 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237 }
1238 /* Drop the argument parsing error as narrow strings
1239 are also valid. */
1240 PyErr_Clear();
1241 }
1242#endif
1243
Tim Peters5aa91602002-01-30 05:46:57 +00001244 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001245 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001247 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001248
Barry Warsaw53699e91996-12-10 23:23:01 +00001249 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001250 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001251 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001252
1253 if (res != 0) {
1254#ifdef MS_WINDOWS
1255 result = win32_error("stat", pathfree);
1256#else
1257 result = posix_error_with_filename(pathfree);
1258#endif
1259 }
1260 else
1261 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001262
Tim Peters500bd032001-12-19 19:05:01 +00001263 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001264 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265}
1266
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267/* POSIX methods */
1268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001269PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001270"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001271Use the real uid/gid to test for access to a path. Note that most\n\
1272operations will use the effective uid/gid, therefore this routine can\n\
1273be used in a suid/sgid environment to test if the invoking user has the\n\
1274specified access to the path. The mode argument can be F_OK to test\n\
1275existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001276
1277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001279{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001280 char *path;
1281 int mode;
1282 int res;
1283
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001284#ifdef Py_WIN_WIDE_FILENAMES
1285 if (unicode_file_names()) {
1286 PyUnicodeObject *po;
1287 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1288 Py_BEGIN_ALLOW_THREADS
1289 /* PyUnicode_AS_UNICODE OK without thread lock as
1290 it is a simple dereference. */
1291 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1292 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001293 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001294 }
1295 /* Drop the argument parsing error as narrow strings
1296 are also valid. */
1297 PyErr_Clear();
1298 }
1299#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001300 if (!PyArg_ParseTuple(args, "eti:access",
1301 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001302 return NULL;
1303 Py_BEGIN_ALLOW_THREADS
1304 res = access(path, mode);
1305 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001306 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001307 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001308}
1309
Guido van Rossumd371ff11999-01-25 16:12:23 +00001310#ifndef F_OK
1311#define F_OK 0
1312#endif
1313#ifndef R_OK
1314#define R_OK 4
1315#endif
1316#ifndef W_OK
1317#define W_OK 2
1318#endif
1319#ifndef X_OK
1320#define X_OK 1
1321#endif
1322
1323#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001324PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001325"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001326Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001327
1328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001329posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001330{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001331 int id;
1332 char *ret;
1333
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001334 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001335 return NULL;
1336
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001337#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001338 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001339 if (id == 0) {
1340 ret = ttyname();
1341 }
1342 else {
1343 ret = NULL;
1344 }
1345#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001346 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001347#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001348 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001349 return posix_error();
1350 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001351}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001352#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001353
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001354#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001355PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001356"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001358
1359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001360posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001361{
1362 char *ret;
1363 char buffer[L_ctermid];
1364
Greg Wardb48bc172000-03-01 21:51:56 +00001365#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001366 ret = ctermid_r(buffer);
1367#else
1368 ret = ctermid(buffer);
1369#endif
1370 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001371 return posix_error();
1372 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001373}
1374#endif
1375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001376PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001377"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001378Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001379
Barry Warsaw53699e91996-12-10 23:23:01 +00001380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001381posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001382{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001383#ifdef MS_WINDOWS
1384 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1385#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1386 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001387#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001388 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001389 NULL, NULL);
1390#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001391 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001392#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393}
1394
Fred Drake4d1e64b2002-04-15 19:40:07 +00001395#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001396PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001397"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001398Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001399opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001400
1401static PyObject *
1402posix_fchdir(PyObject *self, PyObject *fdobj)
1403{
1404 return posix_fildes(fdobj, fchdir);
1405}
1406#endif /* HAVE_FCHDIR */
1407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001409PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001410"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001411Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001412
Barry Warsaw53699e91996-12-10 23:23:01 +00001413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001414posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001415{
Mark Hammondef8b6542001-05-13 08:04:26 +00001416 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001417 int i;
1418 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001419#ifdef Py_WIN_WIDE_FILENAMES
1420 if (unicode_file_names()) {
1421 PyUnicodeObject *po;
1422 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1423 Py_BEGIN_ALLOW_THREADS
1424 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1425 Py_END_ALLOW_THREADS
1426 if (res < 0)
1427 return posix_error_with_unicode_filename(
1428 PyUnicode_AS_UNICODE(po));
1429 Py_INCREF(Py_None);
1430 return Py_None;
1431 }
1432 /* Drop the argument parsing error as narrow strings
1433 are also valid. */
1434 PyErr_Clear();
1435 }
1436#endif /* Py_WIN_WIDE_FILENAMES */
1437 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001438 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001439 return NULL;
1440 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001441 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001442 Py_END_ALLOW_THREADS
1443 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001444 return posix_error_with_allocated_filename(path);
1445 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001446 Py_INCREF(Py_None);
1447 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001448}
1449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001450
Martin v. Löwis244edc82001-10-04 22:44:26 +00001451#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001452PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001453"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001454Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001455
1456static PyObject *
1457posix_chroot(PyObject *self, PyObject *args)
1458{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001460}
1461#endif
1462
Guido van Rossum21142a01999-01-08 21:05:37 +00001463#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001464PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001465"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001467
1468static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001469posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001470{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001471 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001472}
1473#endif /* HAVE_FSYNC */
1474
1475#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001476
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001477#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001478extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1479#endif
1480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001481PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001482"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001483force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001484 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001485
1486static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001487posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001488{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001489 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001490}
1491#endif /* HAVE_FDATASYNC */
1492
1493
Fredrik Lundh10723342000-07-10 16:38:09 +00001494#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001495PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001496"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001497Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Barry Warsaw53699e91996-12-10 23:23:01 +00001499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001500posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001501{
Mark Hammondef8b6542001-05-13 08:04:26 +00001502 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001503 int uid, gid;
1504 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001505 if (!PyArg_ParseTuple(args, "etii:chown",
1506 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001507 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001508 return NULL;
1509 Py_BEGIN_ALLOW_THREADS
1510 res = chown(path, (uid_t) uid, (gid_t) gid);
1511 Py_END_ALLOW_THREADS
1512 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001513 return posix_error_with_allocated_filename(path);
1514 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001515 Py_INCREF(Py_None);
1516 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001517}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001518#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001520#ifdef HAVE_LCHOWN
1521PyDoc_STRVAR(posix_lchown__doc__,
1522"lchown(path, uid, gid)\n\n\
1523Change the owner and group id of path to the numeric uid and gid.\n\
1524This function will not follow symbolic links.");
1525
1526static PyObject *
1527posix_lchown(PyObject *self, PyObject *args)
1528{
1529 char *path = NULL;
1530 int uid, gid;
1531 int res;
1532 if (!PyArg_ParseTuple(args, "etii:lchown",
1533 Py_FileSystemDefaultEncoding, &path,
1534 &uid, &gid))
1535 return NULL;
1536 Py_BEGIN_ALLOW_THREADS
1537 res = lchown(path, (uid_t) uid, (gid_t) gid);
1538 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001539 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001540 return posix_error_with_allocated_filename(path);
1541 PyMem_Free(path);
1542 Py_INCREF(Py_None);
1543 return Py_None;
1544}
1545#endif /* HAVE_LCHOWN */
1546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001547
Guido van Rossum36bc6801995-06-14 22:54:23 +00001548#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001549PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001550"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001551Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001552
Barry Warsaw53699e91996-12-10 23:23:01 +00001553static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001554posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001555{
1556 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001557 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001558
Barry Warsaw53699e91996-12-10 23:23:01 +00001559 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001560#if defined(PYOS_OS2) && defined(PYCC_GCC)
1561 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001562#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001563 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001564#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001566 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001567 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001568 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001569}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001570
Walter Dörwald3b918c32002-11-21 20:18:46 +00001571#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001572PyDoc_STRVAR(posix_getcwdu__doc__,
1573"getcwdu() -> path\n\n\
1574Return a unicode string representing the current working directory.");
1575
1576static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001577posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001578{
1579 char buf[1026];
1580 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001581
1582#ifdef Py_WIN_WIDE_FILENAMES
1583 if (unicode_file_names()) {
1584 wchar_t *wres;
1585 wchar_t wbuf[1026];
1586 Py_BEGIN_ALLOW_THREADS
1587 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1588 Py_END_ALLOW_THREADS
1589 if (wres == NULL)
1590 return posix_error();
1591 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1592 }
1593#endif
1594
1595 Py_BEGIN_ALLOW_THREADS
1596#if defined(PYOS_OS2) && defined(PYCC_GCC)
1597 res = _getcwd2(buf, sizeof buf);
1598#else
1599 res = getcwd(buf, sizeof buf);
1600#endif
1601 Py_END_ALLOW_THREADS
1602 if (res == NULL)
1603 return posix_error();
1604 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1605}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001606#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001607#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001609
Guido van Rossumb6775db1994-08-01 11:34:53 +00001610#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001611PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001612"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001614
Barry Warsaw53699e91996-12-10 23:23:01 +00001615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001616posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001618 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001619}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001620#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001624"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001625Return a list containing the names of the entries in the directory.\n\
1626\n\
1627 path: path of directory to list\n\
1628\n\
1629The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001631
Barry Warsaw53699e91996-12-10 23:23:01 +00001632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001633posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001634{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001635 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001636 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001637#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001638
Barry Warsaw53699e91996-12-10 23:23:01 +00001639 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001640 HANDLE hFindFile;
1641 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001642 /* MAX_PATH characters could mean a bigger encoded string */
1643 char namebuf[MAX_PATH*2+5];
1644 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001645 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001646
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647#ifdef Py_WIN_WIDE_FILENAMES
1648 /* If on wide-character-capable OS see if argument
1649 is Unicode and if so use wide API. */
1650 if (unicode_file_names()) {
1651 PyUnicodeObject *po;
1652 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1653 WIN32_FIND_DATAW wFileData;
1654 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1655 Py_UNICODE wch;
1656 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1657 wnamebuf[MAX_PATH] = L'\0';
1658 len = wcslen(wnamebuf);
1659 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1660 if (wch != L'/' && wch != L'\\' && wch != L':')
1661 wnamebuf[len++] = L'/';
1662 wcscpy(wnamebuf + len, L"*.*");
1663 if ((d = PyList_New(0)) == NULL)
1664 return NULL;
1665 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1666 if (hFindFile == INVALID_HANDLE_VALUE) {
1667 errno = GetLastError();
1668 if (errno == ERROR_FILE_NOT_FOUND) {
1669 return d;
1670 }
1671 Py_DECREF(d);
1672 return win32_error_unicode("FindFirstFileW", wnamebuf);
1673 }
1674 do {
1675 if (wFileData.cFileName[0] == L'.' &&
1676 (wFileData.cFileName[1] == L'\0' ||
1677 wFileData.cFileName[1] == L'.' &&
1678 wFileData.cFileName[2] == L'\0'))
1679 continue;
1680 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1681 if (v == NULL) {
1682 Py_DECREF(d);
1683 d = NULL;
1684 break;
1685 }
1686 if (PyList_Append(d, v) != 0) {
1687 Py_DECREF(v);
1688 Py_DECREF(d);
1689 d = NULL;
1690 break;
1691 }
1692 Py_DECREF(v);
1693 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1694
1695 if (FindClose(hFindFile) == FALSE) {
1696 Py_DECREF(d);
1697 return win32_error_unicode("FindClose", wnamebuf);
1698 }
1699 return d;
1700 }
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1704 }
1705#endif
1706
Tim Peters5aa91602002-01-30 05:46:57 +00001707 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001709 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001710 if (len > 0) {
1711 char ch = namebuf[len-1];
1712 if (ch != SEP && ch != ALTSEP && ch != ':')
1713 namebuf[len++] = '/';
1714 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001715 strcpy(namebuf + len, "*.*");
1716
Barry Warsaw53699e91996-12-10 23:23:01 +00001717 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001718 return NULL;
1719
1720 hFindFile = FindFirstFile(namebuf, &FileData);
1721 if (hFindFile == INVALID_HANDLE_VALUE) {
1722 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001723 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001724 return d;
1725 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001726 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001727 }
1728 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001729 if (FileData.cFileName[0] == '.' &&
1730 (FileData.cFileName[1] == '\0' ||
1731 FileData.cFileName[1] == '.' &&
1732 FileData.cFileName[2] == '\0'))
1733 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001734 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001735 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001736 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001737 d = NULL;
1738 break;
1739 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001740 if (PyList_Append(d, v) != 0) {
1741 Py_DECREF(v);
1742 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001743 d = NULL;
1744 break;
1745 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001746 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001747 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1748
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001749 if (FindClose(hFindFile) == FALSE) {
1750 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001751 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001752 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001753
1754 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001755
Tim Peters0bb44a42000-09-15 07:44:49 +00001756#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001757
1758#ifndef MAX_PATH
1759#define MAX_PATH CCHMAXPATH
1760#endif
1761 char *name, *pt;
1762 int len;
1763 PyObject *d, *v;
1764 char namebuf[MAX_PATH+5];
1765 HDIR hdir = 1;
1766 ULONG srchcnt = 1;
1767 FILEFINDBUF3 ep;
1768 APIRET rc;
1769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001770 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001771 return NULL;
1772 if (len >= MAX_PATH) {
1773 PyErr_SetString(PyExc_ValueError, "path too long");
1774 return NULL;
1775 }
1776 strcpy(namebuf, name);
1777 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001778 if (*pt == ALTSEP)
1779 *pt = SEP;
1780 if (namebuf[len-1] != SEP)
1781 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001782 strcpy(namebuf + len, "*.*");
1783
1784 if ((d = PyList_New(0)) == NULL)
1785 return NULL;
1786
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001787 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1788 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001789 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001790 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1791 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1792 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001793
1794 if (rc != NO_ERROR) {
1795 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001796 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001797 }
1798
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001799 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001800 do {
1801 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001802 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001803 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001804
1805 strcpy(namebuf, ep.achName);
1806
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001807 /* Leave Case of Name Alone -- In Native Form */
1808 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001809
1810 v = PyString_FromString(namebuf);
1811 if (v == NULL) {
1812 Py_DECREF(d);
1813 d = NULL;
1814 break;
1815 }
1816 if (PyList_Append(d, v) != 0) {
1817 Py_DECREF(v);
1818 Py_DECREF(d);
1819 d = NULL;
1820 break;
1821 }
1822 Py_DECREF(v);
1823 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1824 }
1825
1826 return d;
1827#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001828
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001829 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001830 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001831 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001832 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001833 int arg_is_unicode = 1;
1834
1835 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1836 arg_is_unicode = 0;
1837 PyErr_Clear();
1838 }
1839 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001840 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001841 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001842 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001843 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001844 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001846 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847 return NULL;
1848 }
1849 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001850 if (ep->d_name[0] == '.' &&
1851 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001852 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001853 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001854 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857 d = NULL;
1858 break;
1859 }
Just van Rossum46c97842003-02-25 21:42:15 +00001860#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001861 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001862 PyObject *w;
1863
1864 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001865 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001866 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001867 if (w != NULL) {
1868 Py_DECREF(v);
1869 v = w;
1870 }
1871 else {
1872 /* fall back to the original byte string, as
1873 discussed in patch #683592 */
1874 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001875 }
Just van Rossum46c97842003-02-25 21:42:15 +00001876 }
1877#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001878 if (PyList_Append(d, v) != 0) {
1879 Py_DECREF(v);
1880 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001881 d = NULL;
1882 break;
1883 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001884 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 }
1886 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001887 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001888
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001889 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001890
Tim Peters0bb44a42000-09-15 07:44:49 +00001891#endif /* which OS */
1892} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001893
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001894#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001895/* A helper function for abspath on win32 */
1896static PyObject *
1897posix__getfullpathname(PyObject *self, PyObject *args)
1898{
1899 /* assume encoded strings wont more than double no of chars */
1900 char inbuf[MAX_PATH*2];
1901 char *inbufp = inbuf;
1902 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1903 char outbuf[MAX_PATH*2];
1904 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001905#ifdef Py_WIN_WIDE_FILENAMES
1906 if (unicode_file_names()) {
1907 PyUnicodeObject *po;
1908 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1909 Py_UNICODE woutbuf[MAX_PATH*2];
1910 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001911 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001912 sizeof(woutbuf)/sizeof(woutbuf[0]),
1913 woutbuf, &wtemp))
1914 return win32_error("GetFullPathName", "");
1915 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1916 }
1917 /* Drop the argument parsing error as narrow strings
1918 are also valid. */
1919 PyErr_Clear();
1920 }
1921#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001922 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1923 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001924 &insize))
1925 return NULL;
1926 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1927 outbuf, &temp))
1928 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001929 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1930 return PyUnicode_Decode(outbuf, strlen(outbuf),
1931 Py_FileSystemDefaultEncoding, NULL);
1932 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001933 return PyString_FromString(outbuf);
1934} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001935#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001936
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001938"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001940
Barry Warsaw53699e91996-12-10 23:23:01 +00001941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001942posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001943{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001944 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001945 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001946 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001947
1948#ifdef Py_WIN_WIDE_FILENAMES
1949 if (unicode_file_names()) {
1950 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001951 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001952 Py_BEGIN_ALLOW_THREADS
1953 /* PyUnicode_AS_UNICODE OK without thread lock as
1954 it is a simple dereference. */
1955 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1956 Py_END_ALLOW_THREADS
1957 if (res < 0)
1958 return posix_error();
1959 Py_INCREF(Py_None);
1960 return Py_None;
1961 }
1962 /* Drop the argument parsing error as narrow strings
1963 are also valid. */
1964 PyErr_Clear();
1965 }
1966#endif
1967
Tim Peters5aa91602002-01-30 05:46:57 +00001968 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001969 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001970 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001971 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001972#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001973 res = mkdir(path);
1974#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001975 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001976#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001978 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001979 return posix_error_with_allocated_filename(path);
1980 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001981 Py_INCREF(Py_None);
1982 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001983}
1984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001985
Guido van Rossumb6775db1994-08-01 11:34:53 +00001986#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001987#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1988#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1989#include <sys/resource.h>
1990#endif
1991#endif
1992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001993PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001994"nice(inc) -> new_priority\n\n\
1995Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996
Barry Warsaw53699e91996-12-10 23:23:01 +00001997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001998posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001999{
2000 int increment, value;
2001
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002003 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002004
2005 /* There are two flavours of 'nice': one that returns the new
2006 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002007 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2008 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002009
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002010 If we are of the nice family that returns the new priority, we
2011 need to clear errno before the call, and check if errno is filled
2012 before calling posix_error() on a returnvalue of -1, because the
2013 -1 may be the actual new priority! */
2014
2015 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002016 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002017#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002018 if (value == 0)
2019 value = getpriority(PRIO_PROCESS, 0);
2020#endif
2021 if (value == -1 && errno != 0)
2022 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002026#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002030"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Barry Warsaw53699e91996-12-10 23:23:01 +00002033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002034posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002035{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002036#ifdef MS_WINDOWS
2037 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2038#else
2039 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2040#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002041}
2042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002045"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047
Barry Warsaw53699e91996-12-10 23:23:01 +00002048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002049posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002050{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002051#ifdef MS_WINDOWS
2052 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2053#else
2054 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2055#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056}
2057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002059PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002060"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002061Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062
Barry Warsaw53699e91996-12-10 23:23:01 +00002063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002064posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002065{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002066#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002067 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068#else
2069 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2070#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002071}
2072
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002073
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002074#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002076"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002078
Barry Warsaw53699e91996-12-10 23:23:01 +00002079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002082 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002083 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002084 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002085 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002087 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002088 Py_END_ALLOW_THREADS
2089 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002090}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002091#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002094PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002095"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002096Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002097
Barry Warsaw53699e91996-12-10 23:23:01 +00002098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002099posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002100{
2101 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002102 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002104 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105 if (i < 0)
2106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002107 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108}
2109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002110
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002111PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002112"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002116"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002117Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118
Barry Warsaw53699e91996-12-10 23:23:01 +00002119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002120posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002121{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002122#ifdef MS_WINDOWS
2123 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2124#else
2125 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2126#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002127}
2128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002129
Guido van Rossumb6775db1994-08-01 11:34:53 +00002130#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002132"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002133Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002134
Barry Warsaw53699e91996-12-10 23:23:01 +00002135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002136posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002137{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002138 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002139 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002140
Barry Warsaw53699e91996-12-10 23:23:01 +00002141 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002142 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002143 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002144 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002147 u.sysname,
2148 u.nodename,
2149 u.release,
2150 u.version,
2151 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002152}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002153#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002154
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002155static int
2156extract_time(PyObject *t, long* sec, long* usec)
2157{
2158 long intval;
2159 if (PyFloat_Check(t)) {
2160 double tval = PyFloat_AsDouble(t);
2161 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2162 if (!intobj)
2163 return -1;
2164 intval = PyInt_AsLong(intobj);
2165 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002166 if (intval == -1 && PyErr_Occurred())
2167 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002168 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002169 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002170 if (*usec < 0)
2171 /* If rounding gave us a negative number,
2172 truncate. */
2173 *usec = 0;
2174 return 0;
2175 }
2176 intval = PyInt_AsLong(t);
2177 if (intval == -1 && PyErr_Occurred())
2178 return -1;
2179 *sec = intval;
2180 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002181 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002182}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002184PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002185"utime(path, (atime, utime))\n\
2186utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002187Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002188second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002189
Barry Warsaw53699e91996-12-10 23:23:01 +00002190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002191posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002192{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002193 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002194 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002195 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002196 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002197
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002198#if defined(HAVE_UTIMES)
2199 struct timeval buf[2];
2200#define ATIME buf[0].tv_sec
2201#define MTIME buf[1].tv_sec
2202#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002203/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002204 struct utimbuf buf;
2205#define ATIME buf.actime
2206#define MTIME buf.modtime
2207#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002208#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002209 time_t buf[2];
2210#define ATIME buf[0]
2211#define MTIME buf[1]
2212#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002213#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002214
Mark Hammond817c9292003-12-03 01:22:38 +00002215 int have_unicode_filename = 0;
2216#ifdef Py_WIN_WIDE_FILENAMES
2217 PyUnicodeObject *obwpath;
2218 wchar_t *wpath;
2219 if (unicode_file_names()) {
2220 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2221 wpath = PyUnicode_AS_UNICODE(obwpath);
2222 have_unicode_filename = 1;
2223 } else
2224 /* Drop the argument parsing error as narrow strings
2225 are also valid. */
2226 PyErr_Clear();
2227 }
2228#endif /* Py_WIN_WIDE_FILENAMES */
2229
2230 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002231 !PyArg_ParseTuple(args, "etO:utime",
2232 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002233 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002234 if (arg == Py_None) {
2235 /* optional time values not given */
2236 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002237#ifdef Py_WIN_WIDE_FILENAMES
2238 if (have_unicode_filename)
2239 res = _wutime(wpath, NULL);
2240 else
2241#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002242 res = utime(path, NULL);
2243 Py_END_ALLOW_THREADS
2244 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002245 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002246 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002247 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002248 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002249 return NULL;
2250 }
2251 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002252 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002253 &atime, &ausec) == -1) {
2254 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002255 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002256 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002257 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002258 &mtime, &musec) == -1) {
2259 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002260 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002261 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002262 ATIME = atime;
2263 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002264#ifdef HAVE_UTIMES
2265 buf[0].tv_usec = ausec;
2266 buf[1].tv_usec = musec;
2267 Py_BEGIN_ALLOW_THREADS
2268 res = utimes(path, buf);
2269 Py_END_ALLOW_THREADS
2270#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002271 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002272#ifdef Py_WIN_WIDE_FILENAMES
2273 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002274 /* utime is OK with utimbuf, but _wutime insists
2275 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002276 underscore version is ansi) */
2277 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2278 else
2279#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002280 res = utime(path, UTIME_ARG);
2281 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002282#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002283 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002284 if (res < 0) {
2285#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002286 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002287 return posix_error_with_unicode_filename(wpath);
2288#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002289 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002290 }
Neal Norwitz96652712004-06-06 20:40:27 +00002291 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002292 Py_INCREF(Py_None);
2293 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002294#undef UTIME_ARG
2295#undef ATIME
2296#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002297}
2298
Guido van Rossum85e3b011991-06-03 12:42:10 +00002299
Guido van Rossum3b066191991-06-04 19:40:25 +00002300/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002303"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002305
Barry Warsaw53699e91996-12-10 23:23:01 +00002306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002307posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002308{
2309 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002310 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002311 return NULL;
2312 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002313 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002314}
2315
Martin v. Löwis114619e2002-10-07 06:44:21 +00002316#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2317static void
2318free_string_array(char **array, int count)
2319{
2320 int i;
2321 for (i = 0; i < count; i++)
2322 PyMem_Free(array[i]);
2323 PyMem_DEL(array);
2324}
2325#endif
2326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002327
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002328#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002329PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002330"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331Execute an executable path with arguments, replacing current process.\n\
2332\n\
2333 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002334 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002335
Barry Warsaw53699e91996-12-10 23:23:01 +00002336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002337posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002338{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002339 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002340 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002341 char **argvlist;
2342 int i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002343 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002344
Guido van Rossum89b33251993-10-22 14:26:06 +00002345 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002346 argv is a list or tuple of strings. */
2347
Martin v. Löwis114619e2002-10-07 06:44:21 +00002348 if (!PyArg_ParseTuple(args, "etO:execv",
2349 Py_FileSystemDefaultEncoding,
2350 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002351 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002352 if (PyList_Check(argv)) {
2353 argc = PyList_Size(argv);
2354 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002355 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 else if (PyTuple_Check(argv)) {
2357 argc = PyTuple_Size(argv);
2358 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002359 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002360 else {
Fred Drake661ea262000-10-24 19:57:45 +00002361 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002362 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002363 return NULL;
2364 }
2365
Barry Warsaw53699e91996-12-10 23:23:01 +00002366 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 if (argvlist == NULL) {
2368 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002369 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002371 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 if (!PyArg_Parse((*getitem)(argv, i), "et",
2373 Py_FileSystemDefaultEncoding,
2374 &argvlist[i])) {
2375 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002376 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002377 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002378 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002379 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002380
Guido van Rossum85e3b011991-06-03 12:42:10 +00002381 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002382 }
2383 argvlist[argc] = NULL;
2384
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002385 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002386
Guido van Rossum85e3b011991-06-03 12:42:10 +00002387 /* If we get here it's definitely an error */
2388
Martin v. Löwis114619e2002-10-07 06:44:21 +00002389 free_string_array(argvlist, argc);
2390 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002391 return posix_error();
2392}
2393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002395PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002396"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002397Execute a path with arguments and environment, replacing current process.\n\
2398\n\
2399 path: path of executable file\n\
2400 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002401 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002402
Barry Warsaw53699e91996-12-10 23:23:01 +00002403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002404posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002405{
2406 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002407 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002408 char **argvlist;
2409 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002410 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002411 int i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002412 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002413 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002414
2415 /* execve has three arguments: (path, argv, env), where
2416 argv is a list or tuple of strings and env is a dictionary
2417 like posix.environ. */
2418
Martin v. Löwis114619e2002-10-07 06:44:21 +00002419 if (!PyArg_ParseTuple(args, "etOO:execve",
2420 Py_FileSystemDefaultEncoding,
2421 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002422 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002423 if (PyList_Check(argv)) {
2424 argc = PyList_Size(argv);
2425 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002426 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002427 else if (PyTuple_Check(argv)) {
2428 argc = PyTuple_Size(argv);
2429 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002430 }
2431 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002432 PyErr_SetString(PyExc_TypeError,
2433 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002434 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002435 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002436 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002437 PyErr_SetString(PyExc_TypeError,
2438 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002439 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002440 }
2441
Barry Warsaw53699e91996-12-10 23:23:01 +00002442 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002443 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002444 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002445 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002446 }
2447 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002448 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002449 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002450 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002451 &argvlist[i]))
2452 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002453 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002454 goto fail_1;
2455 }
2456 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002458 argvlist[argc] = NULL;
2459
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002460 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002461 if (i < 0)
2462 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002463 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002464 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002465 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002466 goto fail_1;
2467 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002469 keys = PyMapping_Keys(env);
2470 vals = PyMapping_Values(env);
2471 if (!keys || !vals)
2472 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002473 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2474 PyErr_SetString(PyExc_TypeError,
2475 "execve(): env.keys() or env.values() is not a list");
2476 goto fail_2;
2477 }
Tim Peters5aa91602002-01-30 05:46:57 +00002478
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002479 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002480 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002481 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002482
2483 key = PyList_GetItem(keys, pos);
2484 val = PyList_GetItem(vals, pos);
2485 if (!key || !val)
2486 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002487
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002488 if (!PyArg_Parse(
2489 key,
2490 "s;execve() arg 3 contains a non-string key",
2491 &k) ||
2492 !PyArg_Parse(
2493 val,
2494 "s;execve() arg 3 contains a non-string value",
2495 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002496 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002497 goto fail_2;
2498 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002499
2500#if defined(PYOS_OS2)
2501 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2502 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2503#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002504 len = PyString_Size(key) + PyString_Size(val) + 2;
2505 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002506 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002507 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002508 goto fail_2;
2509 }
Tim Petersc8996f52001-12-03 20:41:00 +00002510 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002511 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002512#if defined(PYOS_OS2)
2513 }
2514#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002515 }
2516 envlist[envc] = 0;
2517
2518 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002519
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002520 /* If we get here it's definitely an error */
2521
2522 (void) posix_error();
2523
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002524 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002525 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002526 PyMem_DEL(envlist[envc]);
2527 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002528 fail_1:
2529 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002530 Py_XDECREF(vals);
2531 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002532 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002533 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002534 return NULL;
2535}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002536#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002538
Guido van Rossuma1065681999-01-25 23:20:23 +00002539#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002541"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002542Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002543\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002544 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002545 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002546 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002547
2548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002549posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002550{
2551 char *path;
2552 PyObject *argv;
2553 char **argvlist;
2554 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002555 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002556 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002557
2558 /* spawnv has three arguments: (mode, path, argv), where
2559 argv is a list or tuple of strings. */
2560
Martin v. Löwis114619e2002-10-07 06:44:21 +00002561 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2562 Py_FileSystemDefaultEncoding,
2563 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002564 return NULL;
2565 if (PyList_Check(argv)) {
2566 argc = PyList_Size(argv);
2567 getitem = PyList_GetItem;
2568 }
2569 else if (PyTuple_Check(argv)) {
2570 argc = PyTuple_Size(argv);
2571 getitem = PyTuple_GetItem;
2572 }
2573 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002574 PyErr_SetString(PyExc_TypeError,
2575 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002576 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002577 return NULL;
2578 }
2579
2580 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002581 if (argvlist == NULL) {
2582 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002583 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002584 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002585 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 if (!PyArg_Parse((*getitem)(argv, i), "et",
2587 Py_FileSystemDefaultEncoding,
2588 &argvlist[i])) {
2589 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002590 PyErr_SetString(
2591 PyExc_TypeError,
2592 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002593 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002594 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002595 }
2596 }
2597 argvlist[argc] = NULL;
2598
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002599#if defined(PYOS_OS2) && defined(PYCC_GCC)
2600 Py_BEGIN_ALLOW_THREADS
2601 spawnval = spawnv(mode, path, argvlist);
2602 Py_END_ALLOW_THREADS
2603#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002604 if (mode == _OLD_P_OVERLAY)
2605 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002606
Tim Peters25059d32001-12-07 20:35:43 +00002607 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002608 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002609 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002610#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002611
Martin v. Löwis114619e2002-10-07 06:44:21 +00002612 free_string_array(argvlist, argc);
2613 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002614
Fred Drake699f3522000-06-29 21:12:41 +00002615 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002616 return posix_error();
2617 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002618#if SIZEOF_LONG == SIZEOF_VOID_P
2619 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002620#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002621 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002622#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002623}
2624
2625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002627"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002628Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002629\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002630 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002631 path: path of executable file\n\
2632 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002633 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002634
2635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002636posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002637{
2638 char *path;
2639 PyObject *argv, *env;
2640 char **argvlist;
2641 char **envlist;
2642 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2643 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002644 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002645 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002646 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002647
2648 /* spawnve has four arguments: (mode, path, argv, env), where
2649 argv is a list or tuple of strings and env is a dictionary
2650 like posix.environ. */
2651
Martin v. Löwis114619e2002-10-07 06:44:21 +00002652 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2653 Py_FileSystemDefaultEncoding,
2654 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002655 return NULL;
2656 if (PyList_Check(argv)) {
2657 argc = PyList_Size(argv);
2658 getitem = PyList_GetItem;
2659 }
2660 else if (PyTuple_Check(argv)) {
2661 argc = PyTuple_Size(argv);
2662 getitem = PyTuple_GetItem;
2663 }
2664 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002665 PyErr_SetString(PyExc_TypeError,
2666 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002667 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002668 }
2669 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002670 PyErr_SetString(PyExc_TypeError,
2671 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002672 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002673 }
2674
2675 argvlist = PyMem_NEW(char *, argc+1);
2676 if (argvlist == NULL) {
2677 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002678 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002679 }
2680 for (i = 0; i < argc; i++) {
2681 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002682 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002683 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002684 &argvlist[i]))
2685 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002686 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002687 goto fail_1;
2688 }
2689 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002691 argvlist[argc] = NULL;
2692
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002693 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002694 if (i < 0)
2695 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002696 envlist = PyMem_NEW(char *, i + 1);
2697 if (envlist == NULL) {
2698 PyErr_NoMemory();
2699 goto fail_1;
2700 }
2701 envc = 0;
2702 keys = PyMapping_Keys(env);
2703 vals = PyMapping_Values(env);
2704 if (!keys || !vals)
2705 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002706 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2707 PyErr_SetString(PyExc_TypeError,
2708 "spawnve(): env.keys() or env.values() is not a list");
2709 goto fail_2;
2710 }
Tim Peters5aa91602002-01-30 05:46:57 +00002711
Guido van Rossuma1065681999-01-25 23:20:23 +00002712 for (pos = 0; pos < i; pos++) {
2713 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002714 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002715
2716 key = PyList_GetItem(keys, pos);
2717 val = PyList_GetItem(vals, pos);
2718 if (!key || !val)
2719 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002720
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002721 if (!PyArg_Parse(
2722 key,
2723 "s;spawnve() arg 3 contains a non-string key",
2724 &k) ||
2725 !PyArg_Parse(
2726 val,
2727 "s;spawnve() arg 3 contains a non-string value",
2728 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002729 {
2730 goto fail_2;
2731 }
Tim Petersc8996f52001-12-03 20:41:00 +00002732 len = PyString_Size(key) + PyString_Size(val) + 2;
2733 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002734 if (p == NULL) {
2735 PyErr_NoMemory();
2736 goto fail_2;
2737 }
Tim Petersc8996f52001-12-03 20:41:00 +00002738 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002739 envlist[envc++] = p;
2740 }
2741 envlist[envc] = 0;
2742
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002743#if defined(PYOS_OS2) && defined(PYCC_GCC)
2744 Py_BEGIN_ALLOW_THREADS
2745 spawnval = spawnve(mode, path, argvlist, envlist);
2746 Py_END_ALLOW_THREADS
2747#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002748 if (mode == _OLD_P_OVERLAY)
2749 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002750
2751 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002752 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002753 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002754#endif
Tim Peters25059d32001-12-07 20:35:43 +00002755
Fred Drake699f3522000-06-29 21:12:41 +00002756 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002757 (void) posix_error();
2758 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002759#if SIZEOF_LONG == SIZEOF_VOID_P
2760 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002761#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002762 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002763#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002764
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002765 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002766 while (--envc >= 0)
2767 PyMem_DEL(envlist[envc]);
2768 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002769 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002770 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002771 Py_XDECREF(vals);
2772 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002773 fail_0:
2774 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002775 return res;
2776}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002777
2778/* OS/2 supports spawnvp & spawnvpe natively */
2779#if defined(PYOS_OS2)
2780PyDoc_STRVAR(posix_spawnvp__doc__,
2781"spawnvp(mode, file, args)\n\n\
2782Execute the program 'file' in a new process, using the environment\n\
2783search path to find the file.\n\
2784\n\
2785 mode: mode of process creation\n\
2786 file: executable file name\n\
2787 args: tuple or list of strings");
2788
2789static PyObject *
2790posix_spawnvp(PyObject *self, PyObject *args)
2791{
2792 char *path;
2793 PyObject *argv;
2794 char **argvlist;
2795 int mode, i, argc;
2796 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002797 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002798
2799 /* spawnvp has three arguments: (mode, path, argv), where
2800 argv is a list or tuple of strings. */
2801
2802 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2803 Py_FileSystemDefaultEncoding,
2804 &path, &argv))
2805 return NULL;
2806 if (PyList_Check(argv)) {
2807 argc = PyList_Size(argv);
2808 getitem = PyList_GetItem;
2809 }
2810 else if (PyTuple_Check(argv)) {
2811 argc = PyTuple_Size(argv);
2812 getitem = PyTuple_GetItem;
2813 }
2814 else {
2815 PyErr_SetString(PyExc_TypeError,
2816 "spawnvp() arg 2 must be a tuple or list");
2817 PyMem_Free(path);
2818 return NULL;
2819 }
2820
2821 argvlist = PyMem_NEW(char *, argc+1);
2822 if (argvlist == NULL) {
2823 PyMem_Free(path);
2824 return PyErr_NoMemory();
2825 }
2826 for (i = 0; i < argc; i++) {
2827 if (!PyArg_Parse((*getitem)(argv, i), "et",
2828 Py_FileSystemDefaultEncoding,
2829 &argvlist[i])) {
2830 free_string_array(argvlist, i);
2831 PyErr_SetString(
2832 PyExc_TypeError,
2833 "spawnvp() arg 2 must contain only strings");
2834 PyMem_Free(path);
2835 return NULL;
2836 }
2837 }
2838 argvlist[argc] = NULL;
2839
2840 Py_BEGIN_ALLOW_THREADS
2841#if defined(PYCC_GCC)
2842 spawnval = spawnvp(mode, path, argvlist);
2843#else
2844 spawnval = _spawnvp(mode, path, argvlist);
2845#endif
2846 Py_END_ALLOW_THREADS
2847
2848 free_string_array(argvlist, argc);
2849 PyMem_Free(path);
2850
2851 if (spawnval == -1)
2852 return posix_error();
2853 else
2854 return Py_BuildValue("l", (long) spawnval);
2855}
2856
2857
2858PyDoc_STRVAR(posix_spawnvpe__doc__,
2859"spawnvpe(mode, file, args, env)\n\n\
2860Execute the program 'file' in a new process, using the environment\n\
2861search path to find the file.\n\
2862\n\
2863 mode: mode of process creation\n\
2864 file: executable file name\n\
2865 args: tuple or list of arguments\n\
2866 env: dictionary of strings mapping to strings");
2867
2868static PyObject *
2869posix_spawnvpe(PyObject *self, PyObject *args)
2870{
2871 char *path;
2872 PyObject *argv, *env;
2873 char **argvlist;
2874 char **envlist;
2875 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2876 int mode, i, pos, argc, envc;
2877 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002878 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002879 int lastarg = 0;
2880
2881 /* spawnvpe has four arguments: (mode, path, argv, env), where
2882 argv is a list or tuple of strings and env is a dictionary
2883 like posix.environ. */
2884
2885 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2886 Py_FileSystemDefaultEncoding,
2887 &path, &argv, &env))
2888 return NULL;
2889 if (PyList_Check(argv)) {
2890 argc = PyList_Size(argv);
2891 getitem = PyList_GetItem;
2892 }
2893 else if (PyTuple_Check(argv)) {
2894 argc = PyTuple_Size(argv);
2895 getitem = PyTuple_GetItem;
2896 }
2897 else {
2898 PyErr_SetString(PyExc_TypeError,
2899 "spawnvpe() arg 2 must be a tuple or list");
2900 goto fail_0;
2901 }
2902 if (!PyMapping_Check(env)) {
2903 PyErr_SetString(PyExc_TypeError,
2904 "spawnvpe() arg 3 must be a mapping object");
2905 goto fail_0;
2906 }
2907
2908 argvlist = PyMem_NEW(char *, argc+1);
2909 if (argvlist == NULL) {
2910 PyErr_NoMemory();
2911 goto fail_0;
2912 }
2913 for (i = 0; i < argc; i++) {
2914 if (!PyArg_Parse((*getitem)(argv, i),
2915 "et;spawnvpe() arg 2 must contain only strings",
2916 Py_FileSystemDefaultEncoding,
2917 &argvlist[i]))
2918 {
2919 lastarg = i;
2920 goto fail_1;
2921 }
2922 }
2923 lastarg = argc;
2924 argvlist[argc] = NULL;
2925
2926 i = PyMapping_Size(env);
2927 if (i < 0)
2928 goto fail_1;
2929 envlist = PyMem_NEW(char *, i + 1);
2930 if (envlist == NULL) {
2931 PyErr_NoMemory();
2932 goto fail_1;
2933 }
2934 envc = 0;
2935 keys = PyMapping_Keys(env);
2936 vals = PyMapping_Values(env);
2937 if (!keys || !vals)
2938 goto fail_2;
2939 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2940 PyErr_SetString(PyExc_TypeError,
2941 "spawnvpe(): env.keys() or env.values() is not a list");
2942 goto fail_2;
2943 }
2944
2945 for (pos = 0; pos < i; pos++) {
2946 char *p, *k, *v;
2947 size_t len;
2948
2949 key = PyList_GetItem(keys, pos);
2950 val = PyList_GetItem(vals, pos);
2951 if (!key || !val)
2952 goto fail_2;
2953
2954 if (!PyArg_Parse(
2955 key,
2956 "s;spawnvpe() arg 3 contains a non-string key",
2957 &k) ||
2958 !PyArg_Parse(
2959 val,
2960 "s;spawnvpe() arg 3 contains a non-string value",
2961 &v))
2962 {
2963 goto fail_2;
2964 }
2965 len = PyString_Size(key) + PyString_Size(val) + 2;
2966 p = PyMem_NEW(char, len);
2967 if (p == NULL) {
2968 PyErr_NoMemory();
2969 goto fail_2;
2970 }
2971 PyOS_snprintf(p, len, "%s=%s", k, v);
2972 envlist[envc++] = p;
2973 }
2974 envlist[envc] = 0;
2975
2976 Py_BEGIN_ALLOW_THREADS
2977#if defined(PYCC_GCC)
2978 spawnval = spawnve(mode, path, argvlist, envlist);
2979#else
2980 spawnval = _spawnve(mode, path, argvlist, envlist);
2981#endif
2982 Py_END_ALLOW_THREADS
2983
2984 if (spawnval == -1)
2985 (void) posix_error();
2986 else
2987 res = Py_BuildValue("l", (long) spawnval);
2988
2989 fail_2:
2990 while (--envc >= 0)
2991 PyMem_DEL(envlist[envc]);
2992 PyMem_DEL(envlist);
2993 fail_1:
2994 free_string_array(argvlist, lastarg);
2995 Py_XDECREF(vals);
2996 Py_XDECREF(keys);
2997 fail_0:
2998 PyMem_Free(path);
2999 return res;
3000}
3001#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003002#endif /* HAVE_SPAWNV */
3003
3004
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003005#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003007"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003008Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3009\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003010Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003011
3012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003013posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003014{
Neal Norwitze241ce82003-02-17 18:17:05 +00003015 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003016 if (pid == -1)
3017 return posix_error();
3018 PyOS_AfterFork();
3019 return PyInt_FromLong((long)pid);
3020}
3021#endif
3022
3023
Guido van Rossumad0ee831995-03-01 10:34:45 +00003024#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003029
Barry Warsaw53699e91996-12-10 23:23:01 +00003030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003031posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003032{
Neal Norwitze241ce82003-02-17 18:17:05 +00003033 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003034 if (pid == -1)
3035 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003036 if (pid == 0)
3037 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003038 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003039}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003040#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003041
Neal Norwitzb59798b2003-03-21 01:43:31 +00003042/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003043/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3044#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003045#define DEV_PTY_FILE "/dev/ptc"
3046#define HAVE_DEV_PTMX
3047#else
3048#define DEV_PTY_FILE "/dev/ptmx"
3049#endif
3050
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003051#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003052#ifdef HAVE_PTY_H
3053#include <pty.h>
3054#else
3055#ifdef HAVE_LIBUTIL_H
3056#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003057#endif /* HAVE_LIBUTIL_H */
3058#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003059#ifdef HAVE_STROPTS_H
3060#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003061#endif
3062#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003063
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003064#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003066"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003068
3069static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003070posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003071{
3072 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003073#ifndef HAVE_OPENPTY
3074 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003075#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003076#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003077 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003078#ifdef sun
3079 extern char *ptsname();
3080#endif
3081#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003082
Thomas Wouters70c21a12000-07-14 14:28:33 +00003083#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003084 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3085 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003086#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003087 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3088 if (slave_name == NULL)
3089 return posix_error();
3090
3091 slave_fd = open(slave_name, O_RDWR);
3092 if (slave_fd < 0)
3093 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003094#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003095 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003096 if (master_fd < 0)
3097 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003098 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003099 /* change permission of slave */
3100 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003101 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003102 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003103 }
3104 /* unlock slave */
3105 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003106 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003107 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003108 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003109 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003110 slave_name = ptsname(master_fd); /* get name of slave */
3111 if (slave_name == NULL)
3112 return posix_error();
3113 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3114 if (slave_fd < 0)
3115 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003116#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003117 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3118 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003119#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003120 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003121#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003122#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003123#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003124
Fred Drake8cef4cf2000-06-28 16:40:38 +00003125 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003126
Fred Drake8cef4cf2000-06-28 16:40:38 +00003127}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003128#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003129
3130#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003132"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003133Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3134Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003135To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003136
3137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003138posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003139{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003140 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003141
Fred Drake8cef4cf2000-06-28 16:40:38 +00003142 pid = forkpty(&master_fd, NULL, NULL, NULL);
3143 if (pid == -1)
3144 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003145 if (pid == 0)
3146 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003147 return Py_BuildValue("(ii)", pid, master_fd);
3148}
3149#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150
Guido van Rossumad0ee831995-03-01 10:34:45 +00003151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Barry Warsaw53699e91996-12-10 23:23:01 +00003156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003158{
Barry Warsaw53699e91996-12-10 23:23:01 +00003159 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Guido van Rossumad0ee831995-03-01 10:34:45 +00003164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003168
Barry Warsaw53699e91996-12-10 23:23:01 +00003169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003171{
Barry Warsaw53699e91996-12-10 23:23:01 +00003172 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003176
Guido van Rossumad0ee831995-03-01 10:34:45 +00003177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Barry Warsaw53699e91996-12-10 23:23:01 +00003182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003184{
Barry Warsaw53699e91996-12-10 23:23:01 +00003185 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003193
Barry Warsaw53699e91996-12-10 23:23:01 +00003194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003196{
Barry Warsaw53699e91996-12-10 23:23:01 +00003197 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003198}
3199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Fred Drakec9680921999-12-13 16:37:25 +00003201#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003202PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003203"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003205
3206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003207posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003208{
3209 PyObject *result = NULL;
3210
Fred Drakec9680921999-12-13 16:37:25 +00003211#ifdef NGROUPS_MAX
3212#define MAX_GROUPS NGROUPS_MAX
3213#else
3214 /* defined to be 16 on Solaris7, so this should be a small number */
3215#define MAX_GROUPS 64
3216#endif
3217 gid_t grouplist[MAX_GROUPS];
3218 int n;
3219
3220 n = getgroups(MAX_GROUPS, grouplist);
3221 if (n < 0)
3222 posix_error();
3223 else {
3224 result = PyList_New(n);
3225 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003226 int i;
3227 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003228 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003229 if (o == NULL) {
3230 Py_DECREF(result);
3231 result = NULL;
3232 break;
3233 }
3234 PyList_SET_ITEM(result, i, o);
3235 }
3236 }
3237 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003238
Fred Drakec9680921999-12-13 16:37:25 +00003239 return result;
3240}
3241#endif
3242
Martin v. Löwis606edc12002-06-13 21:09:11 +00003243#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003244PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003245"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003246Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003247
3248static PyObject *
3249posix_getpgid(PyObject *self, PyObject *args)
3250{
3251 int pid, pgid;
3252 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3253 return NULL;
3254 pgid = getpgid(pid);
3255 if (pgid < 0)
3256 return posix_error();
3257 return PyInt_FromLong((long)pgid);
3258}
3259#endif /* HAVE_GETPGID */
3260
3261
Guido van Rossumb6775db1994-08-01 11:34:53 +00003262#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003264"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003265Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003268posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003269{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003270#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003272#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003273 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003274#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003275}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003276#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278
Guido van Rossumb6775db1994-08-01 11:34:53 +00003279#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003280PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003281"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003283
Barry Warsaw53699e91996-12-10 23:23:01 +00003284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003285posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003286{
Guido van Rossum64933891994-10-20 21:56:42 +00003287#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003288 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003289#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003291#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003292 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003293 Py_INCREF(Py_None);
3294 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003295}
3296
Guido van Rossumb6775db1994-08-01 11:34:53 +00003297#endif /* HAVE_SETPGRP */
3298
Guido van Rossumad0ee831995-03-01 10:34:45 +00003299#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003300PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003301"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003302Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303
Barry Warsaw53699e91996-12-10 23:23:01 +00003304static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003305posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003306{
Barry Warsaw53699e91996-12-10 23:23:01 +00003307 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003308}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003309#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
Fred Drake12c6e2d1999-12-14 21:25:03 +00003312#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003313PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003314"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003315Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003316
3317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003318posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003319{
Neal Norwitze241ce82003-02-17 18:17:05 +00003320 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003321 char *name;
3322 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003323
Fred Drakea30680b2000-12-06 21:24:28 +00003324 errno = 0;
3325 name = getlogin();
3326 if (name == NULL) {
3327 if (errno)
3328 posix_error();
3329 else
3330 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003331 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003332 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003333 else
3334 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003335 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003336
Fred Drake12c6e2d1999-12-14 21:25:03 +00003337 return result;
3338}
3339#endif
3340
Guido van Rossumad0ee831995-03-01 10:34:45 +00003341#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003342PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003343"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003344Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003345
Barry Warsaw53699e91996-12-10 23:23:01 +00003346static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003347posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003348{
Barry Warsaw53699e91996-12-10 23:23:01 +00003349 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003350}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003351#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003353
Guido van Rossumad0ee831995-03-01 10:34:45 +00003354#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003355PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003356"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003357Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003358
Barry Warsaw53699e91996-12-10 23:23:01 +00003359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003360posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003361{
3362 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003363 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003365#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003366 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3367 APIRET rc;
3368 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003369 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003370
3371 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3372 APIRET rc;
3373 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003374 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003375
3376 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003377 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003378#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379 if (kill(pid, sig) == -1)
3380 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003381#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003382 Py_INCREF(Py_None);
3383 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003384}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003385#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003386
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003387#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003388PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003389"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003390Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003391
3392static PyObject *
3393posix_killpg(PyObject *self, PyObject *args)
3394{
3395 int pgid, sig;
3396 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3397 return NULL;
3398 if (killpg(pgid, sig) == -1)
3399 return posix_error();
3400 Py_INCREF(Py_None);
3401 return Py_None;
3402}
3403#endif
3404
Guido van Rossumc0125471996-06-28 18:55:32 +00003405#ifdef HAVE_PLOCK
3406
3407#ifdef HAVE_SYS_LOCK_H
3408#include <sys/lock.h>
3409#endif
3410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003411PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003412"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003414
Barry Warsaw53699e91996-12-10 23:23:01 +00003415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003416posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003417{
3418 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003419 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003420 return NULL;
3421 if (plock(op) == -1)
3422 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 Py_INCREF(Py_None);
3424 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003425}
3426#endif
3427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003428
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003429#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003430PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003431"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003432Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003434#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003435#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003436static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003437async_system(const char *command)
3438{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003439 char errormsg[256], args[1024];
3440 RESULTCODES rcodes;
3441 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003442
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003443 char *shell = getenv("COMSPEC");
3444 if (!shell)
3445 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003446
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003447 /* avoid overflowing the argument buffer */
3448 if (strlen(shell) + 3 + strlen(command) >= 1024)
3449 return ERROR_NOT_ENOUGH_MEMORY
3450
3451 args[0] = '\0';
3452 strcat(args, shell);
3453 strcat(args, "/c ");
3454 strcat(args, command);
3455
3456 /* execute asynchronously, inheriting the environment */
3457 rc = DosExecPgm(errormsg,
3458 sizeof(errormsg),
3459 EXEC_ASYNC,
3460 args,
3461 NULL,
3462 &rcodes,
3463 shell);
3464 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003465}
3466
Guido van Rossumd48f2521997-12-05 22:19:34 +00003467static FILE *
3468popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003469{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003470 int oldfd, tgtfd;
3471 HFILE pipeh[2];
3472 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003473
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003474 /* mode determines which of stdin or stdout is reconnected to
3475 * the pipe to the child
3476 */
3477 if (strchr(mode, 'r') != NULL) {
3478 tgt_fd = 1; /* stdout */
3479 } else if (strchr(mode, 'w')) {
3480 tgt_fd = 0; /* stdin */
3481 } else {
3482 *err = ERROR_INVALID_ACCESS;
3483 return NULL;
3484 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003485
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003486 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003487 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3488 *err = rc;
3489 return NULL;
3490 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003491
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003492 /* prevent other threads accessing stdio */
3493 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003495 /* reconnect stdio and execute child */
3496 oldfd = dup(tgtfd);
3497 close(tgtfd);
3498 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3499 DosClose(pipeh[tgtfd]);
3500 rc = async_system(command);
3501 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003502
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003503 /* restore stdio */
3504 dup2(oldfd, tgtfd);
3505 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003506
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003507 /* allow other threads access to stdio */
3508 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003510 /* if execution of child was successful return file stream */
3511 if (rc == NO_ERROR)
3512 return fdopen(pipeh[1 - tgtfd], mode);
3513 else {
3514 DosClose(pipeh[1 - tgtfd]);
3515 *err = rc;
3516 return NULL;
3517 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003518}
3519
3520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003521posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522{
3523 char *name;
3524 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003525 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003526 FILE *fp;
3527 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003529 return NULL;
3530 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003531 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003532 Py_END_ALLOW_THREADS
3533 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003534 return os2_error(err);
3535
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003536 f = PyFile_FromFile(fp, name, mode, fclose);
3537 if (f != NULL)
3538 PyFile_SetBufSize(f, bufsize);
3539 return f;
3540}
3541
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003542#elif defined(PYCC_GCC)
3543
3544/* standard posix version of popen() support */
3545static PyObject *
3546posix_popen(PyObject *self, PyObject *args)
3547{
3548 char *name;
3549 char *mode = "r";
3550 int bufsize = -1;
3551 FILE *fp;
3552 PyObject *f;
3553 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3554 return NULL;
3555 Py_BEGIN_ALLOW_THREADS
3556 fp = popen(name, mode);
3557 Py_END_ALLOW_THREADS
3558 if (fp == NULL)
3559 return posix_error();
3560 f = PyFile_FromFile(fp, name, mode, pclose);
3561 if (f != NULL)
3562 PyFile_SetBufSize(f, bufsize);
3563 return f;
3564}
3565
3566/* fork() under OS/2 has lots'o'warts
3567 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3568 * most of this code is a ripoff of the win32 code, but using the
3569 * capabilities of EMX's C library routines
3570 */
3571
3572/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3573#define POPEN_1 1
3574#define POPEN_2 2
3575#define POPEN_3 3
3576#define POPEN_4 4
3577
3578static PyObject *_PyPopen(char *, int, int, int);
3579static int _PyPclose(FILE *file);
3580
3581/*
3582 * Internal dictionary mapping popen* file pointers to process handles,
3583 * for use when retrieving the process exit code. See _PyPclose() below
3584 * for more information on this dictionary's use.
3585 */
3586static PyObject *_PyPopenProcs = NULL;
3587
3588/* os2emx version of popen2()
3589 *
3590 * The result of this function is a pipe (file) connected to the
3591 * process's stdin, and a pipe connected to the process's stdout.
3592 */
3593
3594static PyObject *
3595os2emx_popen2(PyObject *self, PyObject *args)
3596{
3597 PyObject *f;
3598 int tm=0;
3599
3600 char *cmdstring;
3601 char *mode = "t";
3602 int bufsize = -1;
3603 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3604 return NULL;
3605
3606 if (*mode == 't')
3607 tm = O_TEXT;
3608 else if (*mode != 'b') {
3609 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3610 return NULL;
3611 } else
3612 tm = O_BINARY;
3613
3614 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3615
3616 return f;
3617}
3618
3619/*
3620 * Variation on os2emx.popen2
3621 *
3622 * The result of this function is 3 pipes - the process's stdin,
3623 * stdout and stderr
3624 */
3625
3626static PyObject *
3627os2emx_popen3(PyObject *self, PyObject *args)
3628{
3629 PyObject *f;
3630 int tm = 0;
3631
3632 char *cmdstring;
3633 char *mode = "t";
3634 int bufsize = -1;
3635 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3636 return NULL;
3637
3638 if (*mode == 't')
3639 tm = O_TEXT;
3640 else if (*mode != 'b') {
3641 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3642 return NULL;
3643 } else
3644 tm = O_BINARY;
3645
3646 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3647
3648 return f;
3649}
3650
3651/*
3652 * Variation on os2emx.popen2
3653 *
Tim Peters11b23062003-04-23 02:39:17 +00003654 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003655 * and stdout+stderr combined as a single pipe.
3656 */
3657
3658static PyObject *
3659os2emx_popen4(PyObject *self, PyObject *args)
3660{
3661 PyObject *f;
3662 int tm = 0;
3663
3664 char *cmdstring;
3665 char *mode = "t";
3666 int bufsize = -1;
3667 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3668 return NULL;
3669
3670 if (*mode == 't')
3671 tm = O_TEXT;
3672 else if (*mode != 'b') {
3673 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3674 return NULL;
3675 } else
3676 tm = O_BINARY;
3677
3678 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3679
3680 return f;
3681}
3682
3683/* a couple of structures for convenient handling of multiple
3684 * file handles and pipes
3685 */
3686struct file_ref
3687{
3688 int handle;
3689 int flags;
3690};
3691
3692struct pipe_ref
3693{
3694 int rd;
3695 int wr;
3696};
3697
3698/* The following code is derived from the win32 code */
3699
3700static PyObject *
3701_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3702{
3703 struct file_ref stdio[3];
3704 struct pipe_ref p_fd[3];
3705 FILE *p_s[3];
3706 int file_count, i, pipe_err, pipe_pid;
3707 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3708 PyObject *f, *p_f[3];
3709
3710 /* file modes for subsequent fdopen's on pipe handles */
3711 if (mode == O_TEXT)
3712 {
3713 rd_mode = "rt";
3714 wr_mode = "wt";
3715 }
3716 else
3717 {
3718 rd_mode = "rb";
3719 wr_mode = "wb";
3720 }
3721
3722 /* prepare shell references */
3723 if ((shell = getenv("EMXSHELL")) == NULL)
3724 if ((shell = getenv("COMSPEC")) == NULL)
3725 {
3726 errno = ENOENT;
3727 return posix_error();
3728 }
3729
3730 sh_name = _getname(shell);
3731 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3732 opt = "/c";
3733 else
3734 opt = "-c";
3735
3736 /* save current stdio fds + their flags, and set not inheritable */
3737 i = pipe_err = 0;
3738 while (pipe_err >= 0 && i < 3)
3739 {
3740 pipe_err = stdio[i].handle = dup(i);
3741 stdio[i].flags = fcntl(i, F_GETFD, 0);
3742 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3743 i++;
3744 }
3745 if (pipe_err < 0)
3746 {
3747 /* didn't get them all saved - clean up and bail out */
3748 int saved_err = errno;
3749 while (i-- > 0)
3750 {
3751 close(stdio[i].handle);
3752 }
3753 errno = saved_err;
3754 return posix_error();
3755 }
3756
3757 /* create pipe ends */
3758 file_count = 2;
3759 if (n == POPEN_3)
3760 file_count = 3;
3761 i = pipe_err = 0;
3762 while ((pipe_err == 0) && (i < file_count))
3763 pipe_err = pipe((int *)&p_fd[i++]);
3764 if (pipe_err < 0)
3765 {
3766 /* didn't get them all made - clean up and bail out */
3767 while (i-- > 0)
3768 {
3769 close(p_fd[i].wr);
3770 close(p_fd[i].rd);
3771 }
3772 errno = EPIPE;
3773 return posix_error();
3774 }
3775
3776 /* change the actual standard IO streams over temporarily,
3777 * making the retained pipe ends non-inheritable
3778 */
3779 pipe_err = 0;
3780
3781 /* - stdin */
3782 if (dup2(p_fd[0].rd, 0) == 0)
3783 {
3784 close(p_fd[0].rd);
3785 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3786 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3787 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3788 {
3789 close(p_fd[0].wr);
3790 pipe_err = -1;
3791 }
3792 }
3793 else
3794 {
3795 pipe_err = -1;
3796 }
3797
3798 /* - stdout */
3799 if (pipe_err == 0)
3800 {
3801 if (dup2(p_fd[1].wr, 1) == 1)
3802 {
3803 close(p_fd[1].wr);
3804 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3805 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3806 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3807 {
3808 close(p_fd[1].rd);
3809 pipe_err = -1;
3810 }
3811 }
3812 else
3813 {
3814 pipe_err = -1;
3815 }
3816 }
3817
3818 /* - stderr, as required */
3819 if (pipe_err == 0)
3820 switch (n)
3821 {
3822 case POPEN_3:
3823 {
3824 if (dup2(p_fd[2].wr, 2) == 2)
3825 {
3826 close(p_fd[2].wr);
3827 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3828 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3829 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3830 {
3831 close(p_fd[2].rd);
3832 pipe_err = -1;
3833 }
3834 }
3835 else
3836 {
3837 pipe_err = -1;
3838 }
3839 break;
3840 }
3841
3842 case POPEN_4:
3843 {
3844 if (dup2(1, 2) != 2)
3845 {
3846 pipe_err = -1;
3847 }
3848 break;
3849 }
3850 }
3851
3852 /* spawn the child process */
3853 if (pipe_err == 0)
3854 {
3855 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3856 if (pipe_pid == -1)
3857 {
3858 pipe_err = -1;
3859 }
3860 else
3861 {
3862 /* save the PID into the FILE structure
3863 * NOTE: this implementation doesn't actually
3864 * take advantage of this, but do it for
3865 * completeness - AIM Apr01
3866 */
3867 for (i = 0; i < file_count; i++)
3868 p_s[i]->_pid = pipe_pid;
3869 }
3870 }
3871
3872 /* reset standard IO to normal */
3873 for (i = 0; i < 3; i++)
3874 {
3875 dup2(stdio[i].handle, i);
3876 fcntl(i, F_SETFD, stdio[i].flags);
3877 close(stdio[i].handle);
3878 }
3879
3880 /* if any remnant problems, clean up and bail out */
3881 if (pipe_err < 0)
3882 {
3883 for (i = 0; i < 3; i++)
3884 {
3885 close(p_fd[i].rd);
3886 close(p_fd[i].wr);
3887 }
3888 errno = EPIPE;
3889 return posix_error_with_filename(cmdstring);
3890 }
3891
3892 /* build tuple of file objects to return */
3893 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3894 PyFile_SetBufSize(p_f[0], bufsize);
3895 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3896 PyFile_SetBufSize(p_f[1], bufsize);
3897 if (n == POPEN_3)
3898 {
3899 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3900 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003901 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003902 }
3903 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003904 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003905
3906 /*
3907 * Insert the files we've created into the process dictionary
3908 * all referencing the list with the process handle and the
3909 * initial number of files (see description below in _PyPclose).
3910 * Since if _PyPclose later tried to wait on a process when all
3911 * handles weren't closed, it could create a deadlock with the
3912 * child, we spend some energy here to try to ensure that we
3913 * either insert all file handles into the dictionary or none
3914 * at all. It's a little clumsy with the various popen modes
3915 * and variable number of files involved.
3916 */
3917 if (!_PyPopenProcs)
3918 {
3919 _PyPopenProcs = PyDict_New();
3920 }
3921
3922 if (_PyPopenProcs)
3923 {
3924 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3925 int ins_rc[3];
3926
3927 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3928 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3929
3930 procObj = PyList_New(2);
3931 pidObj = PyInt_FromLong((long) pipe_pid);
3932 intObj = PyInt_FromLong((long) file_count);
3933
3934 if (procObj && pidObj && intObj)
3935 {
3936 PyList_SetItem(procObj, 0, pidObj);
3937 PyList_SetItem(procObj, 1, intObj);
3938
3939 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3940 if (fileObj[0])
3941 {
3942 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3943 fileObj[0],
3944 procObj);
3945 }
3946 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3947 if (fileObj[1])
3948 {
3949 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3950 fileObj[1],
3951 procObj);
3952 }
3953 if (file_count >= 3)
3954 {
3955 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3956 if (fileObj[2])
3957 {
3958 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3959 fileObj[2],
3960 procObj);
3961 }
3962 }
3963
3964 if (ins_rc[0] < 0 || !fileObj[0] ||
3965 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3966 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3967 {
3968 /* Something failed - remove any dictionary
3969 * entries that did make it.
3970 */
3971 if (!ins_rc[0] && fileObj[0])
3972 {
3973 PyDict_DelItem(_PyPopenProcs,
3974 fileObj[0]);
3975 }
3976 if (!ins_rc[1] && fileObj[1])
3977 {
3978 PyDict_DelItem(_PyPopenProcs,
3979 fileObj[1]);
3980 }
3981 if (!ins_rc[2] && fileObj[2])
3982 {
3983 PyDict_DelItem(_PyPopenProcs,
3984 fileObj[2]);
3985 }
3986 }
3987 }
Tim Peters11b23062003-04-23 02:39:17 +00003988
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003989 /*
3990 * Clean up our localized references for the dictionary keys
3991 * and value since PyDict_SetItem will Py_INCREF any copies
3992 * that got placed in the dictionary.
3993 */
3994 Py_XDECREF(procObj);
3995 Py_XDECREF(fileObj[0]);
3996 Py_XDECREF(fileObj[1]);
3997 Py_XDECREF(fileObj[2]);
3998 }
3999
4000 /* Child is launched. */
4001 return f;
4002}
4003
4004/*
4005 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4006 * exit code for the child process and return as a result of the close.
4007 *
4008 * This function uses the _PyPopenProcs dictionary in order to map the
4009 * input file pointer to information about the process that was
4010 * originally created by the popen* call that created the file pointer.
4011 * The dictionary uses the file pointer as a key (with one entry
4012 * inserted for each file returned by the original popen* call) and a
4013 * single list object as the value for all files from a single call.
4014 * The list object contains the Win32 process handle at [0], and a file
4015 * count at [1], which is initialized to the total number of file
4016 * handles using that list.
4017 *
4018 * This function closes whichever handle it is passed, and decrements
4019 * the file count in the dictionary for the process handle pointed to
4020 * by this file. On the last close (when the file count reaches zero),
4021 * this function will wait for the child process and then return its
4022 * exit code as the result of the close() operation. This permits the
4023 * files to be closed in any order - it is always the close() of the
4024 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004025 *
4026 * NOTE: This function is currently called with the GIL released.
4027 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004028 */
4029
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004030static int _PyPclose(FILE *file)
4031{
4032 int result;
4033 int exit_code;
4034 int pipe_pid;
4035 PyObject *procObj, *pidObj, *intObj, *fileObj;
4036 int file_count;
4037#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004038 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004039#endif
4040
4041 /* Close the file handle first, to ensure it can't block the
4042 * child from exiting if it's the last handle.
4043 */
4044 result = fclose(file);
4045
4046#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004047 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004048#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004049 if (_PyPopenProcs)
4050 {
4051 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4052 (procObj = PyDict_GetItem(_PyPopenProcs,
4053 fileObj)) != NULL &&
4054 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4055 (intObj = PyList_GetItem(procObj,1)) != NULL)
4056 {
4057 pipe_pid = (int) PyInt_AsLong(pidObj);
4058 file_count = (int) PyInt_AsLong(intObj);
4059
4060 if (file_count > 1)
4061 {
4062 /* Still other files referencing process */
4063 file_count--;
4064 PyList_SetItem(procObj,1,
4065 PyInt_FromLong((long) file_count));
4066 }
4067 else
4068 {
4069 /* Last file for this process */
4070 if (result != EOF &&
4071 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4072 {
4073 /* extract exit status */
4074 if (WIFEXITED(exit_code))
4075 {
4076 result = WEXITSTATUS(exit_code);
4077 }
4078 else
4079 {
4080 errno = EPIPE;
4081 result = -1;
4082 }
4083 }
4084 else
4085 {
4086 /* Indicate failure - this will cause the file object
4087 * to raise an I/O error and translate the last
4088 * error code from errno. We do have a problem with
4089 * last errors that overlap the normal errno table,
4090 * but that's a consistent problem with the file object.
4091 */
4092 result = -1;
4093 }
4094 }
4095
4096 /* Remove this file pointer from dictionary */
4097 PyDict_DelItem(_PyPopenProcs, fileObj);
4098
4099 if (PyDict_Size(_PyPopenProcs) == 0)
4100 {
4101 Py_DECREF(_PyPopenProcs);
4102 _PyPopenProcs = NULL;
4103 }
4104
4105 } /* if object retrieval ok */
4106
4107 Py_XDECREF(fileObj);
4108 } /* if _PyPopenProcs */
4109
4110#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004111 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004112#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004113 return result;
4114}
4115
4116#endif /* PYCC_??? */
4117
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004118#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004119
4120/*
4121 * Portable 'popen' replacement for Win32.
4122 *
4123 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4124 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004125 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004126 */
4127
4128#include <malloc.h>
4129#include <io.h>
4130#include <fcntl.h>
4131
4132/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4133#define POPEN_1 1
4134#define POPEN_2 2
4135#define POPEN_3 3
4136#define POPEN_4 4
4137
4138static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004139static int _PyPclose(FILE *file);
4140
4141/*
4142 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004143 * for use when retrieving the process exit code. See _PyPclose() below
4144 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004145 */
4146static PyObject *_PyPopenProcs = NULL;
4147
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004148
4149/* popen that works from a GUI.
4150 *
4151 * The result of this function is a pipe (file) connected to the
4152 * processes stdin or stdout, depending on the requested mode.
4153 */
4154
4155static PyObject *
4156posix_popen(PyObject *self, PyObject *args)
4157{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004158 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 char *cmdstring;
4162 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004163 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004164 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004165 return NULL;
4166
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 if (*mode == 'r')
4168 tm = _O_RDONLY;
4169 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004170 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004171 return NULL;
4172 } else
4173 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004174
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004175 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004176 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004177 return NULL;
4178 }
4179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004180 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004182 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004183 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004184 else
4185 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4186
4187 return f;
4188}
4189
4190/* Variation on win32pipe.popen
4191 *
4192 * The result of this function is a pipe (file) connected to the
4193 * process's stdin, and a pipe connected to the process's stdout.
4194 */
4195
4196static PyObject *
4197win32_popen2(PyObject *self, PyObject *args)
4198{
4199 PyObject *f;
4200 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004201
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004202 char *cmdstring;
4203 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004204 int bufsize = -1;
4205 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004206 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004207
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004208 if (*mode == 't')
4209 tm = _O_TEXT;
4210 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004211 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004212 return NULL;
4213 } else
4214 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004215
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004216 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004217 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004218 return NULL;
4219 }
4220
4221 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004222
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004223 return f;
4224}
4225
4226/*
4227 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004228 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004229 * The result of this function is 3 pipes - the process's stdin,
4230 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 */
4232
4233static PyObject *
4234win32_popen3(PyObject *self, PyObject *args)
4235{
4236 PyObject *f;
4237 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004238
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004239 char *cmdstring;
4240 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004241 int bufsize = -1;
4242 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004244
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004245 if (*mode == 't')
4246 tm = _O_TEXT;
4247 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004248 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004249 return NULL;
4250 } else
4251 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004252
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004253 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004254 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004255 return NULL;
4256 }
4257
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004258 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004259
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004260 return f;
4261}
4262
4263/*
4264 * Variation on win32pipe.popen
4265 *
Tim Peters5aa91602002-01-30 05:46:57 +00004266 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004267 * and stdout+stderr combined as a single pipe.
4268 */
4269
4270static PyObject *
4271win32_popen4(PyObject *self, PyObject *args)
4272{
4273 PyObject *f;
4274 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004275
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004276 char *cmdstring;
4277 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004278 int bufsize = -1;
4279 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004280 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004281
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 if (*mode == 't')
4283 tm = _O_TEXT;
4284 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004285 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004286 return NULL;
4287 } else
4288 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004289
4290 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004291 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004292 return NULL;
4293 }
4294
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004295 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004296
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004297 return f;
4298}
4299
Mark Hammond08501372001-01-31 07:30:29 +00004300static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004301_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004302 HANDLE hStdin,
4303 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004304 HANDLE hStderr,
4305 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004306{
4307 PROCESS_INFORMATION piProcInfo;
4308 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004309 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004310 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004311 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004312 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004313 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004314
4315 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004316 char *comshell;
4317
Tim Peters92e4dd82002-10-05 01:47:34 +00004318 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004319 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004320 /* x < i, so x fits into an integer */
4321 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004322
4323 /* Explicitly check if we are using COMMAND.COM. If we are
4324 * then use the w9xpopen hack.
4325 */
4326 comshell = s1 + x;
4327 while (comshell >= s1 && *comshell != '\\')
4328 --comshell;
4329 ++comshell;
4330
4331 if (GetVersion() < 0x80000000 &&
4332 _stricmp(comshell, "command.com") != 0) {
4333 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004334 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004335 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004336 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004337 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 }
4339 else {
4340 /*
Tim Peters402d5982001-08-27 06:37:48 +00004341 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4342 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004343 */
Mark Hammond08501372001-01-31 07:30:29 +00004344 char modulepath[_MAX_PATH];
4345 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004346 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4347 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004348 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004349 x = i+1;
4350 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004351 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004352 strncat(modulepath,
4353 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004354 (sizeof(modulepath)/sizeof(modulepath[0]))
4355 -strlen(modulepath));
4356 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004357 /* Eeek - file-not-found - possibly an embedding
4358 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004359 */
Tim Peters5aa91602002-01-30 05:46:57 +00004360 strncpy(modulepath,
4361 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004362 sizeof(modulepath)/sizeof(modulepath[0]));
4363 if (modulepath[strlen(modulepath)-1] != '\\')
4364 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004365 strncat(modulepath,
4366 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004367 (sizeof(modulepath)/sizeof(modulepath[0]))
4368 -strlen(modulepath));
4369 /* No where else to look - raise an easily identifiable
4370 error, rather than leaving Windows to report
4371 "file not found" - as the user is probably blissfully
4372 unaware this shim EXE is used, and it will confuse them.
4373 (well, it confused me for a while ;-)
4374 */
4375 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004376 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004377 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004378 "for popen to work with your shell "
4379 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004380 szConsoleSpawn);
4381 return FALSE;
4382 }
4383 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004384 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004385 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004386 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004387
Tim Peters92e4dd82002-10-05 01:47:34 +00004388 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004389 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004390 /* To maintain correct argument passing semantics,
4391 we pass the command-line as it stands, and allow
4392 quoting to be applied. w9xpopen.exe will then
4393 use its argv vector, and re-quote the necessary
4394 args for the ultimate child process.
4395 */
Tim Peters75cdad52001-11-28 22:07:30 +00004396 PyOS_snprintf(
4397 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004398 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004399 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004400 s1,
4401 s3,
4402 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004403 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004404 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004405 dialog:
4406 "Your program accessed mem currently in use at xxx"
4407 and a hopeful warning about the stability of your
4408 system.
4409 Cost is Ctrl+C wont kill children, but anyone
4410 who cares can have a go!
4411 */
4412 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004413 }
4414 }
4415
4416 /* Could be an else here to try cmd.exe / command.com in the path
4417 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004418 else {
Tim Peters402d5982001-08-27 06:37:48 +00004419 PyErr_SetString(PyExc_RuntimeError,
4420 "Cannot locate a COMSPEC environment variable to "
4421 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004422 return FALSE;
4423 }
Tim Peters5aa91602002-01-30 05:46:57 +00004424
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004425 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4426 siStartInfo.cb = sizeof(STARTUPINFO);
4427 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4428 siStartInfo.hStdInput = hStdin;
4429 siStartInfo.hStdOutput = hStdout;
4430 siStartInfo.hStdError = hStderr;
4431 siStartInfo.wShowWindow = SW_HIDE;
4432
4433 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004434 s2,
4435 NULL,
4436 NULL,
4437 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004438 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004439 NULL,
4440 NULL,
4441 &siStartInfo,
4442 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004443 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004444 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004445
Mark Hammondb37a3732000-08-14 04:47:33 +00004446 /* Return process handle */
4447 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004448 return TRUE;
4449 }
Tim Peters402d5982001-08-27 06:37:48 +00004450 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004451 return FALSE;
4452}
4453
4454/* The following code is based off of KB: Q190351 */
4455
4456static PyObject *
4457_PyPopen(char *cmdstring, int mode, int n)
4458{
4459 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4460 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004461 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004462
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 SECURITY_ATTRIBUTES saAttr;
4464 BOOL fSuccess;
4465 int fd1, fd2, fd3;
4466 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004467 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004468 PyObject *f;
4469
4470 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4471 saAttr.bInheritHandle = TRUE;
4472 saAttr.lpSecurityDescriptor = NULL;
4473
4474 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4475 return win32_error("CreatePipe", NULL);
4476
4477 /* Create new output read handle and the input write handle. Set
4478 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004479 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004480 * being created. */
4481 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004482 GetCurrentProcess(), &hChildStdinWrDup, 0,
4483 FALSE,
4484 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004485 if (!fSuccess)
4486 return win32_error("DuplicateHandle", NULL);
4487
4488 /* Close the inheritable version of ChildStdin
4489 that we're using. */
4490 CloseHandle(hChildStdinWr);
4491
4492 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4493 return win32_error("CreatePipe", NULL);
4494
4495 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004496 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4497 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004498 if (!fSuccess)
4499 return win32_error("DuplicateHandle", NULL);
4500
4501 /* Close the inheritable version of ChildStdout
4502 that we're using. */
4503 CloseHandle(hChildStdoutRd);
4504
4505 if (n != POPEN_4) {
4506 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4507 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004508 fSuccess = DuplicateHandle(GetCurrentProcess(),
4509 hChildStderrRd,
4510 GetCurrentProcess(),
4511 &hChildStderrRdDup, 0,
4512 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004513 if (!fSuccess)
4514 return win32_error("DuplicateHandle", NULL);
4515 /* Close the inheritable version of ChildStdErr that we're using. */
4516 CloseHandle(hChildStderrRd);
4517 }
Tim Peters5aa91602002-01-30 05:46:57 +00004518
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004519 switch (n) {
4520 case POPEN_1:
4521 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4522 case _O_WRONLY | _O_TEXT:
4523 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004524 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004525 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004526 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004527 PyFile_SetBufSize(f, 0);
4528 /* We don't care about these pipes anymore, so close them. */
4529 CloseHandle(hChildStdoutRdDup);
4530 CloseHandle(hChildStderrRdDup);
4531 break;
4532
4533 case _O_RDONLY | _O_TEXT:
4534 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004535 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004536 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004537 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004538 PyFile_SetBufSize(f, 0);
4539 /* We don't care about these pipes anymore, so close them. */
4540 CloseHandle(hChildStdinWrDup);
4541 CloseHandle(hChildStderrRdDup);
4542 break;
4543
4544 case _O_RDONLY | _O_BINARY:
4545 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004546 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004547 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004548 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004549 PyFile_SetBufSize(f, 0);
4550 /* We don't care about these pipes anymore, so close them. */
4551 CloseHandle(hChildStdinWrDup);
4552 CloseHandle(hChildStderrRdDup);
4553 break;
4554
4555 case _O_WRONLY | _O_BINARY:
4556 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004557 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004558 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004559 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004560 PyFile_SetBufSize(f, 0);
4561 /* We don't care about these pipes anymore, so close them. */
4562 CloseHandle(hChildStdoutRdDup);
4563 CloseHandle(hChildStderrRdDup);
4564 break;
4565 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004566 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004568
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004569 case POPEN_2:
4570 case POPEN_4:
4571 {
4572 char *m1, *m2;
4573 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004574
Tim Peters7dca21e2002-08-19 00:42:29 +00004575 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004576 m1 = "r";
4577 m2 = "w";
4578 } else {
4579 m1 = "rb";
4580 m2 = "wb";
4581 }
4582
Martin v. Löwis18e16552006-02-15 17:27:45 +00004583 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004584 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004585 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004587 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004588 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004589 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004590 PyFile_SetBufSize(p2, 0);
4591
4592 if (n != 4)
4593 CloseHandle(hChildStderrRdDup);
4594
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004595 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004596 Py_XDECREF(p1);
4597 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004598 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004599 break;
4600 }
Tim Peters5aa91602002-01-30 05:46:57 +00004601
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 case POPEN_3:
4603 {
4604 char *m1, *m2;
4605 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004606
Tim Peters7dca21e2002-08-19 00:42:29 +00004607 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004608 m1 = "r";
4609 m2 = "w";
4610 } else {
4611 m1 = "rb";
4612 m2 = "wb";
4613 }
4614
Martin v. Löwis18e16552006-02-15 17:27:45 +00004615 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004616 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004617 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004618 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004619 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004620 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004621 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004622 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4623 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004624 PyFile_SetBufSize(p1, 0);
4625 PyFile_SetBufSize(p2, 0);
4626 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004627 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004628 Py_XDECREF(p1);
4629 Py_XDECREF(p2);
4630 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004631 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004632 break;
4633 }
4634 }
4635
4636 if (n == POPEN_4) {
4637 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004638 hChildStdinRd,
4639 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004640 hChildStdoutWr,
4641 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004642 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004643 }
4644 else {
4645 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004646 hChildStdinRd,
4647 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004648 hChildStderrWr,
4649 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004650 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004651 }
4652
Mark Hammondb37a3732000-08-14 04:47:33 +00004653 /*
4654 * Insert the files we've created into the process dictionary
4655 * all referencing the list with the process handle and the
4656 * initial number of files (see description below in _PyPclose).
4657 * Since if _PyPclose later tried to wait on a process when all
4658 * handles weren't closed, it could create a deadlock with the
4659 * child, we spend some energy here to try to ensure that we
4660 * either insert all file handles into the dictionary or none
4661 * at all. It's a little clumsy with the various popen modes
4662 * and variable number of files involved.
4663 */
4664 if (!_PyPopenProcs) {
4665 _PyPopenProcs = PyDict_New();
4666 }
4667
4668 if (_PyPopenProcs) {
4669 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4670 int ins_rc[3];
4671
4672 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4673 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4674
4675 procObj = PyList_New(2);
4676 hProcessObj = PyLong_FromVoidPtr(hProcess);
4677 intObj = PyInt_FromLong(file_count);
4678
4679 if (procObj && hProcessObj && intObj) {
4680 PyList_SetItem(procObj,0,hProcessObj);
4681 PyList_SetItem(procObj,1,intObj);
4682
4683 fileObj[0] = PyLong_FromVoidPtr(f1);
4684 if (fileObj[0]) {
4685 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4686 fileObj[0],
4687 procObj);
4688 }
4689 if (file_count >= 2) {
4690 fileObj[1] = PyLong_FromVoidPtr(f2);
4691 if (fileObj[1]) {
4692 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4693 fileObj[1],
4694 procObj);
4695 }
4696 }
4697 if (file_count >= 3) {
4698 fileObj[2] = PyLong_FromVoidPtr(f3);
4699 if (fileObj[2]) {
4700 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4701 fileObj[2],
4702 procObj);
4703 }
4704 }
4705
4706 if (ins_rc[0] < 0 || !fileObj[0] ||
4707 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4708 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4709 /* Something failed - remove any dictionary
4710 * entries that did make it.
4711 */
4712 if (!ins_rc[0] && fileObj[0]) {
4713 PyDict_DelItem(_PyPopenProcs,
4714 fileObj[0]);
4715 }
4716 if (!ins_rc[1] && fileObj[1]) {
4717 PyDict_DelItem(_PyPopenProcs,
4718 fileObj[1]);
4719 }
4720 if (!ins_rc[2] && fileObj[2]) {
4721 PyDict_DelItem(_PyPopenProcs,
4722 fileObj[2]);
4723 }
4724 }
4725 }
Tim Peters5aa91602002-01-30 05:46:57 +00004726
Mark Hammondb37a3732000-08-14 04:47:33 +00004727 /*
4728 * Clean up our localized references for the dictionary keys
4729 * and value since PyDict_SetItem will Py_INCREF any copies
4730 * that got placed in the dictionary.
4731 */
4732 Py_XDECREF(procObj);
4733 Py_XDECREF(fileObj[0]);
4734 Py_XDECREF(fileObj[1]);
4735 Py_XDECREF(fileObj[2]);
4736 }
4737
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004738 /* Child is launched. Close the parents copy of those pipe
4739 * handles that only the child should have open. You need to
4740 * make sure that no handles to the write end of the output pipe
4741 * are maintained in this process or else the pipe will not close
4742 * when the child process exits and the ReadFile will hang. */
4743
4744 if (!CloseHandle(hChildStdinRd))
4745 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004746
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004747 if (!CloseHandle(hChildStdoutWr))
4748 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004749
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4751 return win32_error("CloseHandle", NULL);
4752
4753 return f;
4754}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004755
4756/*
4757 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4758 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004759 *
4760 * This function uses the _PyPopenProcs dictionary in order to map the
4761 * input file pointer to information about the process that was
4762 * originally created by the popen* call that created the file pointer.
4763 * The dictionary uses the file pointer as a key (with one entry
4764 * inserted for each file returned by the original popen* call) and a
4765 * single list object as the value for all files from a single call.
4766 * The list object contains the Win32 process handle at [0], and a file
4767 * count at [1], which is initialized to the total number of file
4768 * handles using that list.
4769 *
4770 * This function closes whichever handle it is passed, and decrements
4771 * the file count in the dictionary for the process handle pointed to
4772 * by this file. On the last close (when the file count reaches zero),
4773 * this function will wait for the child process and then return its
4774 * exit code as the result of the close() operation. This permits the
4775 * files to be closed in any order - it is always the close() of the
4776 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004777 *
4778 * NOTE: This function is currently called with the GIL released.
4779 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004780 */
Tim Peters736aa322000-09-01 06:51:24 +00004781
Fredrik Lundh56055a42000-07-23 19:47:12 +00004782static int _PyPclose(FILE *file)
4783{
Fredrik Lundh20318932000-07-26 17:29:12 +00004784 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004785 DWORD exit_code;
4786 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004787 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4788 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004789#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004790 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004791#endif
4792
Fredrik Lundh20318932000-07-26 17:29:12 +00004793 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004794 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004795 */
4796 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004797#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004798 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004799#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004800 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004801 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4802 (procObj = PyDict_GetItem(_PyPopenProcs,
4803 fileObj)) != NULL &&
4804 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4805 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4806
4807 hProcess = PyLong_AsVoidPtr(hProcessObj);
4808 file_count = PyInt_AsLong(intObj);
4809
4810 if (file_count > 1) {
4811 /* Still other files referencing process */
4812 file_count--;
4813 PyList_SetItem(procObj,1,
4814 PyInt_FromLong(file_count));
4815 } else {
4816 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004817 if (result != EOF &&
4818 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4819 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004820 /* Possible truncation here in 16-bit environments, but
4821 * real exit codes are just the lower byte in any event.
4822 */
4823 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004824 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004825 /* Indicate failure - this will cause the file object
4826 * to raise an I/O error and translate the last Win32
4827 * error code from errno. We do have a problem with
4828 * last errors that overlap the normal errno table,
4829 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004830 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004831 if (result != EOF) {
4832 /* If the error wasn't from the fclose(), then
4833 * set errno for the file object error handling.
4834 */
4835 errno = GetLastError();
4836 }
4837 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004838 }
4839
4840 /* Free up the native handle at this point */
4841 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004842 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004843
Mark Hammondb37a3732000-08-14 04:47:33 +00004844 /* Remove this file pointer from dictionary */
4845 PyDict_DelItem(_PyPopenProcs, fileObj);
4846
4847 if (PyDict_Size(_PyPopenProcs) == 0) {
4848 Py_DECREF(_PyPopenProcs);
4849 _PyPopenProcs = NULL;
4850 }
4851
4852 } /* if object retrieval ok */
4853
4854 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004855 } /* if _PyPopenProcs */
4856
Tim Peters736aa322000-09-01 06:51:24 +00004857#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004858 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004859#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004860 return result;
4861}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004862
4863#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004865posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004866{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004867 char *name;
4868 char *mode = "r";
4869 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004870 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004871 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004872 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004873 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004874 /* Strip mode of binary or text modifiers */
4875 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4876 mode = "r";
4877 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4878 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004879 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004880 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004882 if (fp == NULL)
4883 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004885 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004887 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004888}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004889
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004890#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004891#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004893
Guido van Rossumb6775db1994-08-01 11:34:53 +00004894#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004896"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897Set the current process's user id.");
4898
Barry Warsaw53699e91996-12-10 23:23:01 +00004899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004901{
4902 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004903 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004904 return NULL;
4905 if (setuid(uid) < 0)
4906 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004907 Py_INCREF(Py_None);
4908 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004909}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004910#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004912
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004913#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004915"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916Set the current process's effective user id.");
4917
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004918static PyObject *
4919posix_seteuid (PyObject *self, PyObject *args)
4920{
4921 int euid;
4922 if (!PyArg_ParseTuple(args, "i", &euid)) {
4923 return NULL;
4924 } else if (seteuid(euid) < 0) {
4925 return posix_error();
4926 } else {
4927 Py_INCREF(Py_None);
4928 return Py_None;
4929 }
4930}
4931#endif /* HAVE_SETEUID */
4932
4933#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004935"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936Set the current process's effective group id.");
4937
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004938static PyObject *
4939posix_setegid (PyObject *self, PyObject *args)
4940{
4941 int egid;
4942 if (!PyArg_ParseTuple(args, "i", &egid)) {
4943 return NULL;
4944 } else if (setegid(egid) < 0) {
4945 return posix_error();
4946 } else {
4947 Py_INCREF(Py_None);
4948 return Py_None;
4949 }
4950}
4951#endif /* HAVE_SETEGID */
4952
4953#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004954PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004955"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956Set the current process's real and effective user ids.");
4957
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004958static PyObject *
4959posix_setreuid (PyObject *self, PyObject *args)
4960{
4961 int ruid, euid;
4962 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4963 return NULL;
4964 } else if (setreuid(ruid, euid) < 0) {
4965 return posix_error();
4966 } else {
4967 Py_INCREF(Py_None);
4968 return Py_None;
4969 }
4970}
4971#endif /* HAVE_SETREUID */
4972
4973#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004975"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004976Set the current process's real and effective group ids.");
4977
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004978static PyObject *
4979posix_setregid (PyObject *self, PyObject *args)
4980{
4981 int rgid, egid;
4982 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4983 return NULL;
4984 } else if (setregid(rgid, egid) < 0) {
4985 return posix_error();
4986 } else {
4987 Py_INCREF(Py_None);
4988 return Py_None;
4989 }
4990}
4991#endif /* HAVE_SETREGID */
4992
Guido van Rossumb6775db1994-08-01 11:34:53 +00004993#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004995"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Barry Warsaw53699e91996-12-10 23:23:01 +00004998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004999posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005000{
5001 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005002 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005003 return NULL;
5004 if (setgid(gid) < 0)
5005 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005006 Py_INCREF(Py_None);
5007 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005008}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005009#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005010
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005011#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005015
5016static PyObject *
5017posix_setgroups(PyObject *self, PyObject *args)
5018{
5019 PyObject *groups;
5020 int i, len;
5021 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005022
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005023 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5024 return NULL;
5025 if (!PySequence_Check(groups)) {
5026 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5027 return NULL;
5028 }
5029 len = PySequence_Size(groups);
5030 if (len > MAX_GROUPS) {
5031 PyErr_SetString(PyExc_ValueError, "too many groups");
5032 return NULL;
5033 }
5034 for(i = 0; i < len; i++) {
5035 PyObject *elem;
5036 elem = PySequence_GetItem(groups, i);
5037 if (!elem)
5038 return NULL;
5039 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005040 if (!PyLong_Check(elem)) {
5041 PyErr_SetString(PyExc_TypeError,
5042 "groups must be integers");
5043 Py_DECREF(elem);
5044 return NULL;
5045 } else {
5046 unsigned long x = PyLong_AsUnsignedLong(elem);
5047 if (PyErr_Occurred()) {
5048 PyErr_SetString(PyExc_TypeError,
5049 "group id too big");
5050 Py_DECREF(elem);
5051 return NULL;
5052 }
5053 grouplist[i] = x;
5054 /* read back the value to see if it fitted in gid_t */
5055 if (grouplist[i] != x) {
5056 PyErr_SetString(PyExc_TypeError,
5057 "group id too big");
5058 Py_DECREF(elem);
5059 return NULL;
5060 }
5061 }
5062 } else {
5063 long x = PyInt_AsLong(elem);
5064 grouplist[i] = x;
5065 if (grouplist[i] != x) {
5066 PyErr_SetString(PyExc_TypeError,
5067 "group id too big");
5068 Py_DECREF(elem);
5069 return NULL;
5070 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005071 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005072 Py_DECREF(elem);
5073 }
5074
5075 if (setgroups(len, grouplist) < 0)
5076 return posix_error();
5077 Py_INCREF(Py_None);
5078 return Py_None;
5079}
5080#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005081
Guido van Rossumb6775db1994-08-01 11:34:53 +00005082#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005083PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005084"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005086
Barry Warsaw53699e91996-12-10 23:23:01 +00005087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005088posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005089{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005090 int pid, options;
5091#ifdef UNION_WAIT
5092 union wait status;
5093#define status_i (status.w_status)
5094#else
5095 int status;
5096#define status_i status
5097#endif
5098 status_i = 0;
5099
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005100 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005101 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005102 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005103 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005104 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005105 if (pid == -1)
5106 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005107 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005108 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005109}
5110
Tim Petersab034fa2002-02-01 11:27:43 +00005111#elif defined(HAVE_CWAIT)
5112
5113/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005114PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005115"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005117
5118static PyObject *
5119posix_waitpid(PyObject *self, PyObject *args)
5120{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005121 intptr_t pid;
5122 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005123
5124 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5125 return NULL;
5126 Py_BEGIN_ALLOW_THREADS
5127 pid = _cwait(&status, pid, options);
5128 Py_END_ALLOW_THREADS
5129 if (pid == -1)
5130 return posix_error();
5131 else
5132 /* shift the status left a byte so this is more like the
5133 POSIX waitpid */
5134 return Py_BuildValue("ii", pid, status << 8);
5135}
5136#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005137
Guido van Rossumad0ee831995-03-01 10:34:45 +00005138#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005139PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005140"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005142
Barry Warsaw53699e91996-12-10 23:23:01 +00005143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005144posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005145{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005147#ifdef UNION_WAIT
5148 union wait status;
5149#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005150#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005151 int status;
5152#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005153#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005154
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005155 status_i = 0;
5156 Py_BEGIN_ALLOW_THREADS
5157 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005158 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005159 if (pid == -1)
5160 return posix_error();
5161 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005162 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005163#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005164}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005165#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005169"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005171
Barry Warsaw53699e91996-12-10 23:23:01 +00005172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005173posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005174{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005175#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005176 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005177#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005178#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005179 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005180#else
5181 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5182#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005183#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005184}
5185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005186
Guido van Rossumb6775db1994-08-01 11:34:53 +00005187#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005188PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005189"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005190Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005191
Barry Warsaw53699e91996-12-10 23:23:01 +00005192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005193posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005194{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005195 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005196 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005197 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005198 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005199 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005200 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005201 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005202 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005203 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005204 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005205 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005206}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005207#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005208
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005209
Guido van Rossumb6775db1994-08-01 11:34:53 +00005210#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005211PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005212"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005213Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005214
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005216posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005217{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005218 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005219}
5220#endif /* HAVE_SYMLINK */
5221
5222
5223#ifdef HAVE_TIMES
5224#ifndef HZ
5225#define HZ 60 /* Universal constant :-) */
5226#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005227
Guido van Rossumd48f2521997-12-05 22:19:34 +00005228#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5229static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005230system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005231{
5232 ULONG value = 0;
5233
5234 Py_BEGIN_ALLOW_THREADS
5235 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5236 Py_END_ALLOW_THREADS
5237
5238 return value;
5239}
5240
5241static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005242posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005243{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005244 /* Currently Only Uptime is Provided -- Others Later */
5245 return Py_BuildValue("ddddd",
5246 (double)0 /* t.tms_utime / HZ */,
5247 (double)0 /* t.tms_stime / HZ */,
5248 (double)0 /* t.tms_cutime / HZ */,
5249 (double)0 /* t.tms_cstime / HZ */,
5250 (double)system_uptime() / 1000);
5251}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005252#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005253static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005254posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005255{
5256 struct tms t;
5257 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005258 errno = 0;
5259 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005260 if (c == (clock_t) -1)
5261 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005262 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005263 (double)t.tms_utime / HZ,
5264 (double)t.tms_stime / HZ,
5265 (double)t.tms_cutime / HZ,
5266 (double)t.tms_cstime / HZ,
5267 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005268}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005269#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005270#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005271
5272
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005273#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005274#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005275static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005276posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005277{
5278 FILETIME create, exit, kernel, user;
5279 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005280 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005281 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5282 /* The fields of a FILETIME structure are the hi and lo part
5283 of a 64-bit value expressed in 100 nanosecond units.
5284 1e7 is one second in such units; 1e-7 the inverse.
5285 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5286 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005287 return Py_BuildValue(
5288 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005289 (double)(kernel.dwHighDateTime*429.4967296 +
5290 kernel.dwLowDateTime*1e-7),
5291 (double)(user.dwHighDateTime*429.4967296 +
5292 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005293 (double)0,
5294 (double)0,
5295 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005296}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005297#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005298
5299#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005300PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005301"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005303#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005305
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005306#ifdef HAVE_GETSID
5307PyDoc_STRVAR(posix_getsid__doc__,
5308"getsid(pid) -> sid\n\n\
5309Call the system call getsid().");
5310
5311static PyObject *
5312posix_getsid(PyObject *self, PyObject *args)
5313{
5314 int pid, sid;
5315 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5316 return NULL;
5317 sid = getsid(pid);
5318 if (sid < 0)
5319 return posix_error();
5320 return PyInt_FromLong((long)sid);
5321}
5322#endif /* HAVE_GETSID */
5323
5324
Guido van Rossumb6775db1994-08-01 11:34:53 +00005325#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005326PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005327"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005328Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005329
Barry Warsaw53699e91996-12-10 23:23:01 +00005330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005331posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005332{
Guido van Rossum687dd131993-05-17 08:34:16 +00005333 if (setsid() < 0)
5334 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005335 Py_INCREF(Py_None);
5336 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005337}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005338#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005339
Guido van Rossumb6775db1994-08-01 11:34:53 +00005340#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005342"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005343Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005344
Barry Warsaw53699e91996-12-10 23:23:01 +00005345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005346posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005347{
5348 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005349 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005350 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005351 if (setpgid(pid, pgrp) < 0)
5352 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005353 Py_INCREF(Py_None);
5354 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005355}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005356#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005358
Guido van Rossumb6775db1994-08-01 11:34:53 +00005359#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005361"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005363
Barry Warsaw53699e91996-12-10 23:23:01 +00005364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005365posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005366{
5367 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005368 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005369 return NULL;
5370 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 if (pgid < 0)
5372 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005373 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005374}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005375#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005377
Guido van Rossumb6775db1994-08-01 11:34:53 +00005378#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005379PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005380"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005382
Barry Warsaw53699e91996-12-10 23:23:01 +00005383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005384posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005385{
5386 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005387 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005388 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005389 if (tcsetpgrp(fd, pgid) < 0)
5390 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005391 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005392 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005393}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005394#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005395
Guido van Rossum687dd131993-05-17 08:34:16 +00005396/* Functions acting on file descriptors */
5397
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005398PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005399"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005401
Barry Warsaw53699e91996-12-10 23:23:01 +00005402static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005403posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005404{
Mark Hammondef8b6542001-05-13 08:04:26 +00005405 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005406 int flag;
5407 int mode = 0777;
5408 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005409
5410#ifdef MS_WINDOWS
5411 if (unicode_file_names()) {
5412 PyUnicodeObject *po;
5413 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5414 Py_BEGIN_ALLOW_THREADS
5415 /* PyUnicode_AS_UNICODE OK without thread
5416 lock as it is a simple dereference. */
5417 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5418 Py_END_ALLOW_THREADS
5419 if (fd < 0)
5420 return posix_error();
5421 return PyInt_FromLong((long)fd);
5422 }
5423 /* Drop the argument parsing error as narrow strings
5424 are also valid. */
5425 PyErr_Clear();
5426 }
5427#endif
5428
Tim Peters5aa91602002-01-30 05:46:57 +00005429 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005430 Py_FileSystemDefaultEncoding, &file,
5431 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005432 return NULL;
5433
Barry Warsaw53699e91996-12-10 23:23:01 +00005434 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005435 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005436 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005437 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005438 return posix_error_with_allocated_filename(file);
5439 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005440 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005441}
5442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005443
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005445"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005446Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005447
Barry Warsaw53699e91996-12-10 23:23:01 +00005448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005449posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005450{
5451 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005452 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005453 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005454 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005455 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005456 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005457 if (res < 0)
5458 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005459 Py_INCREF(Py_None);
5460 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005461}
5462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005465"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005467
Barry Warsaw53699e91996-12-10 23:23:01 +00005468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005469posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005470{
5471 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005472 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005473 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005474 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005475 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005476 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005477 if (fd < 0)
5478 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005479 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005480}
5481
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005484"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005486
Barry Warsaw53699e91996-12-10 23:23:01 +00005487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005488posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005489{
5490 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005492 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005493 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005494 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005496 if (res < 0)
5497 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005498 Py_INCREF(Py_None);
5499 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005500}
5501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005502
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005504"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005506
Barry Warsaw53699e91996-12-10 23:23:01 +00005507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005508posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005509{
5510 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005511#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005512 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005513#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005514 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005515#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005516 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005517 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005518 return NULL;
5519#ifdef SEEK_SET
5520 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5521 switch (how) {
5522 case 0: how = SEEK_SET; break;
5523 case 1: how = SEEK_CUR; break;
5524 case 2: how = SEEK_END; break;
5525 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005526#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005527
5528#if !defined(HAVE_LARGEFILE_SUPPORT)
5529 pos = PyInt_AsLong(posobj);
5530#else
5531 pos = PyLong_Check(posobj) ?
5532 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5533#endif
5534 if (PyErr_Occurred())
5535 return NULL;
5536
Barry Warsaw53699e91996-12-10 23:23:01 +00005537 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005538#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005539 res = _lseeki64(fd, pos, how);
5540#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005541 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005542#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005543 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005544 if (res < 0)
5545 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005546
5547#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005548 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005549#else
5550 return PyLong_FromLongLong(res);
5551#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005552}
5553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005554
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005555PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005556"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005558
Barry Warsaw53699e91996-12-10 23:23:01 +00005559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005560posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005561{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005562 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005563 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005564 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005565 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005566 if (size < 0) {
5567 errno = EINVAL;
5568 return posix_error();
5569 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005570 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005571 if (buffer == NULL)
5572 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 Py_BEGIN_ALLOW_THREADS
5574 n = read(fd, PyString_AsString(buffer), size);
5575 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005576 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005577 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005578 return posix_error();
5579 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005580 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005581 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005582 return buffer;
5583}
5584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005586PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005587"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005589
Barry Warsaw53699e91996-12-10 23:23:01 +00005590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005592{
5593 int fd, size;
5594 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005595 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005596 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005597 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005598 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005599 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005600 if (size < 0)
5601 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005602 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005603}
5604
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Barry Warsaw53699e91996-12-10 23:23:01 +00005610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005612{
5613 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005614 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005615 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005616 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005617 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005618#ifdef __VMS
5619 /* on OpenVMS we must ensure that all bytes are written to the file */
5620 fsync(fd);
5621#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005622 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005623 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005624 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005625 if (res != 0) {
5626#ifdef MS_WINDOWS
5627 return win32_error("fstat", NULL);
5628#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005629 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005630#endif
5631 }
Tim Peters5aa91602002-01-30 05:46:57 +00005632
Martin v. Löwis14694662006-02-03 12:54:16 +00005633 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005634}
5635
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005636
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005637PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005638"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005639Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005640
Barry Warsaw53699e91996-12-10 23:23:01 +00005641static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005642posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005643{
Guido van Rossum687dd131993-05-17 08:34:16 +00005644 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005645 char *mode = "r";
5646 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005647 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005648 PyObject *f;
5649 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005650 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005651
Thomas Heller1f043e22002-11-07 16:00:59 +00005652 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5653 PyErr_Format(PyExc_ValueError,
5654 "invalid file mode '%s'", mode);
5655 return NULL;
5656 }
5657
Barry Warsaw53699e91996-12-10 23:23:01 +00005658 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005659 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005660 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005661 if (fp == NULL)
5662 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005663 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005664 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005665 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005666 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005667}
5668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005670"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005671Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005673
5674static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005675posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005676{
5677 int fd;
5678 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5679 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005680 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005681}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005682
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005683#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005684PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005685"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005686Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005687
Barry Warsaw53699e91996-12-10 23:23:01 +00005688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005689posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005690{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005691#if defined(PYOS_OS2)
5692 HFILE read, write;
5693 APIRET rc;
5694
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005695 Py_BEGIN_ALLOW_THREADS
5696 rc = DosCreatePipe( &read, &write, 4096);
5697 Py_END_ALLOW_THREADS
5698 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005699 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005700
5701 return Py_BuildValue("(ii)", read, write);
5702#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005703#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005704 int fds[2];
5705 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005706 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005707 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005708 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005709 if (res != 0)
5710 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005711 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005712#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005713 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005714 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005715 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005717 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005718 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005719 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005720 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005721 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5722 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005723 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005724#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005725#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005726}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005727#endif /* HAVE_PIPE */
5728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005729
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005730#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005731PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005732"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005734
Barry Warsaw53699e91996-12-10 23:23:01 +00005735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005736posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005737{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005738 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005739 int mode = 0666;
5740 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005741 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005742 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005743 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005744 res = mkfifo(filename, mode);
5745 Py_END_ALLOW_THREADS
5746 if (res < 0)
5747 return posix_error();
5748 Py_INCREF(Py_None);
5749 return Py_None;
5750}
5751#endif
5752
5753
Neal Norwitz11690112002-07-30 01:08:28 +00005754#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005756"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005757Create a filesystem node (file, device special file or named pipe)\n\
5758named filename. mode specifies both the permissions to use and the\n\
5759type of node to be created, being combined (bitwise OR) with one of\n\
5760S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005761device defines the newly created device special file (probably using\n\
5762os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005763
5764
5765static PyObject *
5766posix_mknod(PyObject *self, PyObject *args)
5767{
5768 char *filename;
5769 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005770 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005771 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005772 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005773 return NULL;
5774 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005775 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005776 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005777 if (res < 0)
5778 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005779 Py_INCREF(Py_None);
5780 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005781}
5782#endif
5783
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005784#ifdef HAVE_DEVICE_MACROS
5785PyDoc_STRVAR(posix_major__doc__,
5786"major(device) -> major number\n\
5787Extracts a device major number from a raw device number.");
5788
5789static PyObject *
5790posix_major(PyObject *self, PyObject *args)
5791{
5792 int device;
5793 if (!PyArg_ParseTuple(args, "i:major", &device))
5794 return NULL;
5795 return PyInt_FromLong((long)major(device));
5796}
5797
5798PyDoc_STRVAR(posix_minor__doc__,
5799"minor(device) -> minor number\n\
5800Extracts a device minor number from a raw device number.");
5801
5802static PyObject *
5803posix_minor(PyObject *self, PyObject *args)
5804{
5805 int device;
5806 if (!PyArg_ParseTuple(args, "i:minor", &device))
5807 return NULL;
5808 return PyInt_FromLong((long)minor(device));
5809}
5810
5811PyDoc_STRVAR(posix_makedev__doc__,
5812"makedev(major, minor) -> device number\n\
5813Composes a raw device number from the major and minor device numbers.");
5814
5815static PyObject *
5816posix_makedev(PyObject *self, PyObject *args)
5817{
5818 int major, minor;
5819 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5820 return NULL;
5821 return PyInt_FromLong((long)makedev(major, minor));
5822}
5823#endif /* device macros */
5824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005825
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005826#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005827PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005828"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005829Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005830
Barry Warsaw53699e91996-12-10 23:23:01 +00005831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005832posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005833{
5834 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005835 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005836 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005837 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005838
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005839 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005840 return NULL;
5841
5842#if !defined(HAVE_LARGEFILE_SUPPORT)
5843 length = PyInt_AsLong(lenobj);
5844#else
5845 length = PyLong_Check(lenobj) ?
5846 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5847#endif
5848 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005849 return NULL;
5850
Barry Warsaw53699e91996-12-10 23:23:01 +00005851 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005852 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005853 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005854 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005855 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005856 return NULL;
5857 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005858 Py_INCREF(Py_None);
5859 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005860}
5861#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005862
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005863#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005865"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005866Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005867
Fred Drake762e2061999-08-26 17:23:54 +00005868/* Save putenv() parameters as values here, so we can collect them when they
5869 * get re-set with another call for the same key. */
5870static PyObject *posix_putenv_garbage;
5871
Tim Peters5aa91602002-01-30 05:46:57 +00005872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005873posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005874{
5875 char *s1, *s2;
5876 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005877 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005878 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005879
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005880 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005881 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005882
5883#if defined(PYOS_OS2)
5884 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5885 APIRET rc;
5886
Guido van Rossumd48f2521997-12-05 22:19:34 +00005887 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5888 if (rc != NO_ERROR)
5889 return os2_error(rc);
5890
5891 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5892 APIRET rc;
5893
Guido van Rossumd48f2521997-12-05 22:19:34 +00005894 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5895 if (rc != NO_ERROR)
5896 return os2_error(rc);
5897 } else {
5898#endif
5899
Fred Drake762e2061999-08-26 17:23:54 +00005900 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005901 len = strlen(s1) + strlen(s2) + 2;
5902 /* len includes space for a trailing \0; the size arg to
5903 PyString_FromStringAndSize does not count that */
5904 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005905 if (newstr == NULL)
5906 return PyErr_NoMemory();
5907 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005908 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005909 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005910 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005911 posix_error();
5912 return NULL;
5913 }
Fred Drake762e2061999-08-26 17:23:54 +00005914 /* Install the first arg and newstr in posix_putenv_garbage;
5915 * this will cause previous value to be collected. This has to
5916 * happen after the real putenv() call because the old value
5917 * was still accessible until then. */
5918 if (PyDict_SetItem(posix_putenv_garbage,
5919 PyTuple_GET_ITEM(args, 0), newstr)) {
5920 /* really not much we can do; just leak */
5921 PyErr_Clear();
5922 }
5923 else {
5924 Py_DECREF(newstr);
5925 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005926
5927#if defined(PYOS_OS2)
5928 }
5929#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005930 Py_INCREF(Py_None);
5931 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005932}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005933#endif /* putenv */
5934
Guido van Rossumc524d952001-10-19 01:31:59 +00005935#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005937"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005938Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005939
5940static PyObject *
5941posix_unsetenv(PyObject *self, PyObject *args)
5942{
5943 char *s1;
5944
5945 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5946 return NULL;
5947
5948 unsetenv(s1);
5949
5950 /* Remove the key from posix_putenv_garbage;
5951 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005952 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005953 * old value was still accessible until then.
5954 */
5955 if (PyDict_DelItem(posix_putenv_garbage,
5956 PyTuple_GET_ITEM(args, 0))) {
5957 /* really not much we can do; just leak */
5958 PyErr_Clear();
5959 }
5960
5961 Py_INCREF(Py_None);
5962 return Py_None;
5963}
5964#endif /* unsetenv */
5965
Guido van Rossumb6a47161997-09-15 22:54:34 +00005966#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005967PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005968"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005969Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005970
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005972posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005973{
5974 int code;
5975 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005976 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005977 return NULL;
5978 message = strerror(code);
5979 if (message == NULL) {
5980 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005981 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005982 return NULL;
5983 }
5984 return PyString_FromString(message);
5985}
5986#endif /* strerror */
5987
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005988
Guido van Rossumc9641791998-08-04 15:26:23 +00005989#ifdef HAVE_SYS_WAIT_H
5990
Fred Drake106c1a02002-04-23 15:58:02 +00005991#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005992PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005993"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005995
5996static PyObject *
5997posix_WCOREDUMP(PyObject *self, PyObject *args)
5998{
5999#ifdef UNION_WAIT
6000 union wait status;
6001#define status_i (status.w_status)
6002#else
6003 int status;
6004#define status_i status
6005#endif
6006 status_i = 0;
6007
6008 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6009 {
6010 return NULL;
6011 }
6012
6013 return PyBool_FromLong(WCOREDUMP(status));
6014#undef status_i
6015}
6016#endif /* WCOREDUMP */
6017
6018#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006019PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006020"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006021Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006022job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006023
6024static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006025posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006026{
6027#ifdef UNION_WAIT
6028 union wait status;
6029#define status_i (status.w_status)
6030#else
6031 int status;
6032#define status_i status
6033#endif
6034 status_i = 0;
6035
6036 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6037 {
6038 return NULL;
6039 }
6040
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006041 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006042#undef status_i
6043}
6044#endif /* WIFCONTINUED */
6045
Guido van Rossumc9641791998-08-04 15:26:23 +00006046#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006050
6051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006052posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006053{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006054#ifdef UNION_WAIT
6055 union wait status;
6056#define status_i (status.w_status)
6057#else
6058 int status;
6059#define status_i status
6060#endif
6061 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006062
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006063 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006064 {
6065 return NULL;
6066 }
Tim Peters5aa91602002-01-30 05:46:57 +00006067
Fred Drake106c1a02002-04-23 15:58:02 +00006068 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006069#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006070}
6071#endif /* WIFSTOPPED */
6072
6073#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006075"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006076Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006077
6078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006079posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006080{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006081#ifdef UNION_WAIT
6082 union wait status;
6083#define status_i (status.w_status)
6084#else
6085 int status;
6086#define status_i status
6087#endif
6088 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006089
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006090 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006091 {
6092 return NULL;
6093 }
Tim Peters5aa91602002-01-30 05:46:57 +00006094
Fred Drake106c1a02002-04-23 15:58:02 +00006095 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006096#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006097}
6098#endif /* WIFSIGNALED */
6099
6100#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006101PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006102"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006103Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006105
6106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006107posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006108{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006109#ifdef UNION_WAIT
6110 union wait status;
6111#define status_i (status.w_status)
6112#else
6113 int status;
6114#define status_i status
6115#endif
6116 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006117
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006118 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006119 {
6120 return NULL;
6121 }
Tim Peters5aa91602002-01-30 05:46:57 +00006122
Fred Drake106c1a02002-04-23 15:58:02 +00006123 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006124#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006125}
6126#endif /* WIFEXITED */
6127
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006128#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006130"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006132
6133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006134posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006135{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006136#ifdef UNION_WAIT
6137 union wait status;
6138#define status_i (status.w_status)
6139#else
6140 int status;
6141#define status_i status
6142#endif
6143 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006144
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006145 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006146 {
6147 return NULL;
6148 }
Tim Peters5aa91602002-01-30 05:46:57 +00006149
Guido van Rossumc9641791998-08-04 15:26:23 +00006150 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006151#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006152}
6153#endif /* WEXITSTATUS */
6154
6155#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006157"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006158Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006160
6161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006162posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006163{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006164#ifdef UNION_WAIT
6165 union wait status;
6166#define status_i (status.w_status)
6167#else
6168 int status;
6169#define status_i status
6170#endif
6171 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006172
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006173 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006174 {
6175 return NULL;
6176 }
Tim Peters5aa91602002-01-30 05:46:57 +00006177
Guido van Rossumc9641791998-08-04 15:26:23 +00006178 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006179#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006180}
6181#endif /* WTERMSIG */
6182
6183#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006184PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006185"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006186Return the signal that stopped the process that provided\n\
6187the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006188
6189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006190posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006191{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006192#ifdef UNION_WAIT
6193 union wait status;
6194#define status_i (status.w_status)
6195#else
6196 int status;
6197#define status_i status
6198#endif
6199 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006200
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006201 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006202 {
6203 return NULL;
6204 }
Tim Peters5aa91602002-01-30 05:46:57 +00006205
Guido van Rossumc9641791998-08-04 15:26:23 +00006206 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006207#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006208}
6209#endif /* WSTOPSIG */
6210
6211#endif /* HAVE_SYS_WAIT_H */
6212
6213
Guido van Rossum94f6f721999-01-06 18:42:14 +00006214#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006215#ifdef _SCO_DS
6216/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6217 needed definitions in sys/statvfs.h */
6218#define _SVID3
6219#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006220#include <sys/statvfs.h>
6221
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006222static PyObject*
6223_pystatvfs_fromstructstatvfs(struct statvfs st) {
6224 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6225 if (v == NULL)
6226 return NULL;
6227
6228#if !defined(HAVE_LARGEFILE_SUPPORT)
6229 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6230 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6231 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6232 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6233 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6234 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6235 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6236 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6237 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6238 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6239#else
6240 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6241 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006242 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006243 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006244 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006245 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006246 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006247 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006248 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006249 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006250 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006251 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006252 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006253 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006254 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6255 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6256#endif
6257
6258 return v;
6259}
6260
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006262"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006263Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006264
6265static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006266posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006267{
6268 int fd, res;
6269 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006270
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006271 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006272 return NULL;
6273 Py_BEGIN_ALLOW_THREADS
6274 res = fstatvfs(fd, &st);
6275 Py_END_ALLOW_THREADS
6276 if (res != 0)
6277 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006278
6279 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006280}
6281#endif /* HAVE_FSTATVFS */
6282
6283
6284#if defined(HAVE_STATVFS)
6285#include <sys/statvfs.h>
6286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006288"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006289Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006290
6291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006292posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006293{
6294 char *path;
6295 int res;
6296 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006297 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006298 return NULL;
6299 Py_BEGIN_ALLOW_THREADS
6300 res = statvfs(path, &st);
6301 Py_END_ALLOW_THREADS
6302 if (res != 0)
6303 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006304
6305 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006306}
6307#endif /* HAVE_STATVFS */
6308
6309
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006310#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006312"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006313Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006314The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006316
6317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006318posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006319{
6320 PyObject *result = NULL;
6321 char *dir = NULL;
6322 char *pfx = NULL;
6323 char *name;
6324
6325 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6326 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006327
6328 if (PyErr_Warn(PyExc_RuntimeWarning,
6329 "tempnam is a potential security risk to your program") < 0)
6330 return NULL;
6331
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006332#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006333 name = _tempnam(dir, pfx);
6334#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006335 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006336#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 if (name == NULL)
6338 return PyErr_NoMemory();
6339 result = PyString_FromString(name);
6340 free(name);
6341 return result;
6342}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006343#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006344
6345
6346#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006348"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006349Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006350
6351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006352posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353{
6354 FILE *fp;
6355
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006356 fp = tmpfile();
6357 if (fp == NULL)
6358 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006359 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006360}
6361#endif
6362
6363
6364#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006366"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006367Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368
6369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006370posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371{
6372 char buffer[L_tmpnam];
6373 char *name;
6374
Skip Montanaro95618b52001-08-18 18:52:10 +00006375 if (PyErr_Warn(PyExc_RuntimeWarning,
6376 "tmpnam is a potential security risk to your program") < 0)
6377 return NULL;
6378
Greg Wardb48bc172000-03-01 21:51:56 +00006379#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006380 name = tmpnam_r(buffer);
6381#else
6382 name = tmpnam(buffer);
6383#endif
6384 if (name == NULL) {
6385 PyErr_SetObject(PyExc_OSError,
6386 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006387#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006388 "unexpected NULL from tmpnam_r"
6389#else
6390 "unexpected NULL from tmpnam"
6391#endif
6392 ));
6393 return NULL;
6394 }
6395 return PyString_FromString(buffer);
6396}
6397#endif
6398
6399
Fred Drakec9680921999-12-13 16:37:25 +00006400/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6401 * It maps strings representing configuration variable names to
6402 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006403 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006404 * rarely-used constants. There are three separate tables that use
6405 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006406 *
6407 * This code is always included, even if none of the interfaces that
6408 * need it are included. The #if hackery needed to avoid it would be
6409 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006410 */
6411struct constdef {
6412 char *name;
6413 long value;
6414};
6415
Fred Drake12c6e2d1999-12-14 21:25:03 +00006416static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006417conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6418 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006419{
6420 if (PyInt_Check(arg)) {
6421 *valuep = PyInt_AS_LONG(arg);
6422 return 1;
6423 }
6424 if (PyString_Check(arg)) {
6425 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006426 size_t lo = 0;
6427 size_t mid;
6428 size_t hi = tablesize;
6429 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006430 char *confname = PyString_AS_STRING(arg);
6431 while (lo < hi) {
6432 mid = (lo + hi) / 2;
6433 cmp = strcmp(confname, table[mid].name);
6434 if (cmp < 0)
6435 hi = mid;
6436 else if (cmp > 0)
6437 lo = mid + 1;
6438 else {
6439 *valuep = table[mid].value;
6440 return 1;
6441 }
6442 }
6443 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6444 }
6445 else
6446 PyErr_SetString(PyExc_TypeError,
6447 "configuration names must be strings or integers");
6448 return 0;
6449}
6450
6451
6452#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6453static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006454#ifdef _PC_ABI_AIO_XFER_MAX
6455 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6456#endif
6457#ifdef _PC_ABI_ASYNC_IO
6458 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6459#endif
Fred Drakec9680921999-12-13 16:37:25 +00006460#ifdef _PC_ASYNC_IO
6461 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6462#endif
6463#ifdef _PC_CHOWN_RESTRICTED
6464 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6465#endif
6466#ifdef _PC_FILESIZEBITS
6467 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6468#endif
6469#ifdef _PC_LAST
6470 {"PC_LAST", _PC_LAST},
6471#endif
6472#ifdef _PC_LINK_MAX
6473 {"PC_LINK_MAX", _PC_LINK_MAX},
6474#endif
6475#ifdef _PC_MAX_CANON
6476 {"PC_MAX_CANON", _PC_MAX_CANON},
6477#endif
6478#ifdef _PC_MAX_INPUT
6479 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6480#endif
6481#ifdef _PC_NAME_MAX
6482 {"PC_NAME_MAX", _PC_NAME_MAX},
6483#endif
6484#ifdef _PC_NO_TRUNC
6485 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6486#endif
6487#ifdef _PC_PATH_MAX
6488 {"PC_PATH_MAX", _PC_PATH_MAX},
6489#endif
6490#ifdef _PC_PIPE_BUF
6491 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6492#endif
6493#ifdef _PC_PRIO_IO
6494 {"PC_PRIO_IO", _PC_PRIO_IO},
6495#endif
6496#ifdef _PC_SOCK_MAXBUF
6497 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6498#endif
6499#ifdef _PC_SYNC_IO
6500 {"PC_SYNC_IO", _PC_SYNC_IO},
6501#endif
6502#ifdef _PC_VDISABLE
6503 {"PC_VDISABLE", _PC_VDISABLE},
6504#endif
6505};
6506
Fred Drakec9680921999-12-13 16:37:25 +00006507static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006508conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006509{
6510 return conv_confname(arg, valuep, posix_constants_pathconf,
6511 sizeof(posix_constants_pathconf)
6512 / sizeof(struct constdef));
6513}
6514#endif
6515
6516#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006518"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006519Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006520If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006521
6522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006523posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006524{
6525 PyObject *result = NULL;
6526 int name, fd;
6527
Fred Drake12c6e2d1999-12-14 21:25:03 +00006528 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6529 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006530 long limit;
6531
6532 errno = 0;
6533 limit = fpathconf(fd, name);
6534 if (limit == -1 && errno != 0)
6535 posix_error();
6536 else
6537 result = PyInt_FromLong(limit);
6538 }
6539 return result;
6540}
6541#endif
6542
6543
6544#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006546"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006547Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006549
6550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006551posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006552{
6553 PyObject *result = NULL;
6554 int name;
6555 char *path;
6556
6557 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6558 conv_path_confname, &name)) {
6559 long limit;
6560
6561 errno = 0;
6562 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006563 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006564 if (errno == EINVAL)
6565 /* could be a path or name problem */
6566 posix_error();
6567 else
6568 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006569 }
Fred Drakec9680921999-12-13 16:37:25 +00006570 else
6571 result = PyInt_FromLong(limit);
6572 }
6573 return result;
6574}
6575#endif
6576
6577#ifdef HAVE_CONFSTR
6578static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006579#ifdef _CS_ARCHITECTURE
6580 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6581#endif
6582#ifdef _CS_HOSTNAME
6583 {"CS_HOSTNAME", _CS_HOSTNAME},
6584#endif
6585#ifdef _CS_HW_PROVIDER
6586 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6587#endif
6588#ifdef _CS_HW_SERIAL
6589 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6590#endif
6591#ifdef _CS_INITTAB_NAME
6592 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6593#endif
Fred Drakec9680921999-12-13 16:37:25 +00006594#ifdef _CS_LFS64_CFLAGS
6595 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6596#endif
6597#ifdef _CS_LFS64_LDFLAGS
6598 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6599#endif
6600#ifdef _CS_LFS64_LIBS
6601 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6602#endif
6603#ifdef _CS_LFS64_LINTFLAGS
6604 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6605#endif
6606#ifdef _CS_LFS_CFLAGS
6607 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6608#endif
6609#ifdef _CS_LFS_LDFLAGS
6610 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6611#endif
6612#ifdef _CS_LFS_LIBS
6613 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6614#endif
6615#ifdef _CS_LFS_LINTFLAGS
6616 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6617#endif
Fred Draked86ed291999-12-15 15:34:33 +00006618#ifdef _CS_MACHINE
6619 {"CS_MACHINE", _CS_MACHINE},
6620#endif
Fred Drakec9680921999-12-13 16:37:25 +00006621#ifdef _CS_PATH
6622 {"CS_PATH", _CS_PATH},
6623#endif
Fred Draked86ed291999-12-15 15:34:33 +00006624#ifdef _CS_RELEASE
6625 {"CS_RELEASE", _CS_RELEASE},
6626#endif
6627#ifdef _CS_SRPC_DOMAIN
6628 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6629#endif
6630#ifdef _CS_SYSNAME
6631 {"CS_SYSNAME", _CS_SYSNAME},
6632#endif
6633#ifdef _CS_VERSION
6634 {"CS_VERSION", _CS_VERSION},
6635#endif
Fred Drakec9680921999-12-13 16:37:25 +00006636#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6637 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6638#endif
6639#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6640 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6641#endif
6642#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6643 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6644#endif
6645#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6646 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6647#endif
6648#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6649 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6650#endif
6651#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6652 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6653#endif
6654#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6655 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6656#endif
6657#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6658 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6659#endif
6660#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6661 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6662#endif
6663#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6664 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6665#endif
6666#ifdef _CS_XBS5_LP64_OFF64_LIBS
6667 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6668#endif
6669#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6670 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6671#endif
6672#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6673 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6674#endif
6675#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6676 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6677#endif
6678#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6679 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6680#endif
6681#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6682 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6683#endif
Fred Draked86ed291999-12-15 15:34:33 +00006684#ifdef _MIPS_CS_AVAIL_PROCESSORS
6685 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6686#endif
6687#ifdef _MIPS_CS_BASE
6688 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6689#endif
6690#ifdef _MIPS_CS_HOSTID
6691 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6692#endif
6693#ifdef _MIPS_CS_HW_NAME
6694 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6695#endif
6696#ifdef _MIPS_CS_NUM_PROCESSORS
6697 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6698#endif
6699#ifdef _MIPS_CS_OSREL_MAJ
6700 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6701#endif
6702#ifdef _MIPS_CS_OSREL_MIN
6703 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6704#endif
6705#ifdef _MIPS_CS_OSREL_PATCH
6706 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6707#endif
6708#ifdef _MIPS_CS_OS_NAME
6709 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6710#endif
6711#ifdef _MIPS_CS_OS_PROVIDER
6712 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6713#endif
6714#ifdef _MIPS_CS_PROCESSORS
6715 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6716#endif
6717#ifdef _MIPS_CS_SERIAL
6718 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6719#endif
6720#ifdef _MIPS_CS_VENDOR
6721 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6722#endif
Fred Drakec9680921999-12-13 16:37:25 +00006723};
6724
6725static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006726conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006727{
6728 return conv_confname(arg, valuep, posix_constants_confstr,
6729 sizeof(posix_constants_confstr)
6730 / sizeof(struct constdef));
6731}
6732
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006733PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006734"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006736
6737static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006738posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006739{
6740 PyObject *result = NULL;
6741 int name;
6742 char buffer[64];
6743
6744 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6745 int len = confstr(name, buffer, sizeof(buffer));
6746
Fred Drakec9680921999-12-13 16:37:25 +00006747 errno = 0;
6748 if (len == 0) {
6749 if (errno != 0)
6750 posix_error();
6751 else
6752 result = PyString_FromString("");
6753 }
6754 else {
6755 if (len >= sizeof(buffer)) {
6756 result = PyString_FromStringAndSize(NULL, len);
6757 if (result != NULL)
6758 confstr(name, PyString_AS_STRING(result), len+1);
6759 }
6760 else
6761 result = PyString_FromString(buffer);
6762 }
6763 }
6764 return result;
6765}
6766#endif
6767
6768
6769#ifdef HAVE_SYSCONF
6770static struct constdef posix_constants_sysconf[] = {
6771#ifdef _SC_2_CHAR_TERM
6772 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6773#endif
6774#ifdef _SC_2_C_BIND
6775 {"SC_2_C_BIND", _SC_2_C_BIND},
6776#endif
6777#ifdef _SC_2_C_DEV
6778 {"SC_2_C_DEV", _SC_2_C_DEV},
6779#endif
6780#ifdef _SC_2_C_VERSION
6781 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6782#endif
6783#ifdef _SC_2_FORT_DEV
6784 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6785#endif
6786#ifdef _SC_2_FORT_RUN
6787 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6788#endif
6789#ifdef _SC_2_LOCALEDEF
6790 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6791#endif
6792#ifdef _SC_2_SW_DEV
6793 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6794#endif
6795#ifdef _SC_2_UPE
6796 {"SC_2_UPE", _SC_2_UPE},
6797#endif
6798#ifdef _SC_2_VERSION
6799 {"SC_2_VERSION", _SC_2_VERSION},
6800#endif
Fred Draked86ed291999-12-15 15:34:33 +00006801#ifdef _SC_ABI_ASYNCHRONOUS_IO
6802 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6803#endif
6804#ifdef _SC_ACL
6805 {"SC_ACL", _SC_ACL},
6806#endif
Fred Drakec9680921999-12-13 16:37:25 +00006807#ifdef _SC_AIO_LISTIO_MAX
6808 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6809#endif
Fred Drakec9680921999-12-13 16:37:25 +00006810#ifdef _SC_AIO_MAX
6811 {"SC_AIO_MAX", _SC_AIO_MAX},
6812#endif
6813#ifdef _SC_AIO_PRIO_DELTA_MAX
6814 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6815#endif
6816#ifdef _SC_ARG_MAX
6817 {"SC_ARG_MAX", _SC_ARG_MAX},
6818#endif
6819#ifdef _SC_ASYNCHRONOUS_IO
6820 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6821#endif
6822#ifdef _SC_ATEXIT_MAX
6823 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6824#endif
Fred Draked86ed291999-12-15 15:34:33 +00006825#ifdef _SC_AUDIT
6826 {"SC_AUDIT", _SC_AUDIT},
6827#endif
Fred Drakec9680921999-12-13 16:37:25 +00006828#ifdef _SC_AVPHYS_PAGES
6829 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6830#endif
6831#ifdef _SC_BC_BASE_MAX
6832 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6833#endif
6834#ifdef _SC_BC_DIM_MAX
6835 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6836#endif
6837#ifdef _SC_BC_SCALE_MAX
6838 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6839#endif
6840#ifdef _SC_BC_STRING_MAX
6841 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6842#endif
Fred Draked86ed291999-12-15 15:34:33 +00006843#ifdef _SC_CAP
6844 {"SC_CAP", _SC_CAP},
6845#endif
Fred Drakec9680921999-12-13 16:37:25 +00006846#ifdef _SC_CHARCLASS_NAME_MAX
6847 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6848#endif
6849#ifdef _SC_CHAR_BIT
6850 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6851#endif
6852#ifdef _SC_CHAR_MAX
6853 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6854#endif
6855#ifdef _SC_CHAR_MIN
6856 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6857#endif
6858#ifdef _SC_CHILD_MAX
6859 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6860#endif
6861#ifdef _SC_CLK_TCK
6862 {"SC_CLK_TCK", _SC_CLK_TCK},
6863#endif
6864#ifdef _SC_COHER_BLKSZ
6865 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6866#endif
6867#ifdef _SC_COLL_WEIGHTS_MAX
6868 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6869#endif
6870#ifdef _SC_DCACHE_ASSOC
6871 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6872#endif
6873#ifdef _SC_DCACHE_BLKSZ
6874 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6875#endif
6876#ifdef _SC_DCACHE_LINESZ
6877 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6878#endif
6879#ifdef _SC_DCACHE_SZ
6880 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6881#endif
6882#ifdef _SC_DCACHE_TBLKSZ
6883 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6884#endif
6885#ifdef _SC_DELAYTIMER_MAX
6886 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6887#endif
6888#ifdef _SC_EQUIV_CLASS_MAX
6889 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6890#endif
6891#ifdef _SC_EXPR_NEST_MAX
6892 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6893#endif
6894#ifdef _SC_FSYNC
6895 {"SC_FSYNC", _SC_FSYNC},
6896#endif
6897#ifdef _SC_GETGR_R_SIZE_MAX
6898 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6899#endif
6900#ifdef _SC_GETPW_R_SIZE_MAX
6901 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6902#endif
6903#ifdef _SC_ICACHE_ASSOC
6904 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6905#endif
6906#ifdef _SC_ICACHE_BLKSZ
6907 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6908#endif
6909#ifdef _SC_ICACHE_LINESZ
6910 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6911#endif
6912#ifdef _SC_ICACHE_SZ
6913 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6914#endif
Fred Draked86ed291999-12-15 15:34:33 +00006915#ifdef _SC_INF
6916 {"SC_INF", _SC_INF},
6917#endif
Fred Drakec9680921999-12-13 16:37:25 +00006918#ifdef _SC_INT_MAX
6919 {"SC_INT_MAX", _SC_INT_MAX},
6920#endif
6921#ifdef _SC_INT_MIN
6922 {"SC_INT_MIN", _SC_INT_MIN},
6923#endif
6924#ifdef _SC_IOV_MAX
6925 {"SC_IOV_MAX", _SC_IOV_MAX},
6926#endif
Fred Draked86ed291999-12-15 15:34:33 +00006927#ifdef _SC_IP_SECOPTS
6928 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6929#endif
Fred Drakec9680921999-12-13 16:37:25 +00006930#ifdef _SC_JOB_CONTROL
6931 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6932#endif
Fred Draked86ed291999-12-15 15:34:33 +00006933#ifdef _SC_KERN_POINTERS
6934 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6935#endif
6936#ifdef _SC_KERN_SIM
6937 {"SC_KERN_SIM", _SC_KERN_SIM},
6938#endif
Fred Drakec9680921999-12-13 16:37:25 +00006939#ifdef _SC_LINE_MAX
6940 {"SC_LINE_MAX", _SC_LINE_MAX},
6941#endif
6942#ifdef _SC_LOGIN_NAME_MAX
6943 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6944#endif
6945#ifdef _SC_LOGNAME_MAX
6946 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6947#endif
6948#ifdef _SC_LONG_BIT
6949 {"SC_LONG_BIT", _SC_LONG_BIT},
6950#endif
Fred Draked86ed291999-12-15 15:34:33 +00006951#ifdef _SC_MAC
6952 {"SC_MAC", _SC_MAC},
6953#endif
Fred Drakec9680921999-12-13 16:37:25 +00006954#ifdef _SC_MAPPED_FILES
6955 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6956#endif
6957#ifdef _SC_MAXPID
6958 {"SC_MAXPID", _SC_MAXPID},
6959#endif
6960#ifdef _SC_MB_LEN_MAX
6961 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6962#endif
6963#ifdef _SC_MEMLOCK
6964 {"SC_MEMLOCK", _SC_MEMLOCK},
6965#endif
6966#ifdef _SC_MEMLOCK_RANGE
6967 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6968#endif
6969#ifdef _SC_MEMORY_PROTECTION
6970 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6971#endif
6972#ifdef _SC_MESSAGE_PASSING
6973 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6974#endif
Fred Draked86ed291999-12-15 15:34:33 +00006975#ifdef _SC_MMAP_FIXED_ALIGNMENT
6976 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6977#endif
Fred Drakec9680921999-12-13 16:37:25 +00006978#ifdef _SC_MQ_OPEN_MAX
6979 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6980#endif
6981#ifdef _SC_MQ_PRIO_MAX
6982 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6983#endif
Fred Draked86ed291999-12-15 15:34:33 +00006984#ifdef _SC_NACLS_MAX
6985 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6986#endif
Fred Drakec9680921999-12-13 16:37:25 +00006987#ifdef _SC_NGROUPS_MAX
6988 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6989#endif
6990#ifdef _SC_NL_ARGMAX
6991 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6992#endif
6993#ifdef _SC_NL_LANGMAX
6994 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6995#endif
6996#ifdef _SC_NL_MSGMAX
6997 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6998#endif
6999#ifdef _SC_NL_NMAX
7000 {"SC_NL_NMAX", _SC_NL_NMAX},
7001#endif
7002#ifdef _SC_NL_SETMAX
7003 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7004#endif
7005#ifdef _SC_NL_TEXTMAX
7006 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7007#endif
7008#ifdef _SC_NPROCESSORS_CONF
7009 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7010#endif
7011#ifdef _SC_NPROCESSORS_ONLN
7012 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7013#endif
Fred Draked86ed291999-12-15 15:34:33 +00007014#ifdef _SC_NPROC_CONF
7015 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7016#endif
7017#ifdef _SC_NPROC_ONLN
7018 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7019#endif
Fred Drakec9680921999-12-13 16:37:25 +00007020#ifdef _SC_NZERO
7021 {"SC_NZERO", _SC_NZERO},
7022#endif
7023#ifdef _SC_OPEN_MAX
7024 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7025#endif
7026#ifdef _SC_PAGESIZE
7027 {"SC_PAGESIZE", _SC_PAGESIZE},
7028#endif
7029#ifdef _SC_PAGE_SIZE
7030 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7031#endif
7032#ifdef _SC_PASS_MAX
7033 {"SC_PASS_MAX", _SC_PASS_MAX},
7034#endif
7035#ifdef _SC_PHYS_PAGES
7036 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7037#endif
7038#ifdef _SC_PII
7039 {"SC_PII", _SC_PII},
7040#endif
7041#ifdef _SC_PII_INTERNET
7042 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7043#endif
7044#ifdef _SC_PII_INTERNET_DGRAM
7045 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7046#endif
7047#ifdef _SC_PII_INTERNET_STREAM
7048 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7049#endif
7050#ifdef _SC_PII_OSI
7051 {"SC_PII_OSI", _SC_PII_OSI},
7052#endif
7053#ifdef _SC_PII_OSI_CLTS
7054 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7055#endif
7056#ifdef _SC_PII_OSI_COTS
7057 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7058#endif
7059#ifdef _SC_PII_OSI_M
7060 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7061#endif
7062#ifdef _SC_PII_SOCKET
7063 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7064#endif
7065#ifdef _SC_PII_XTI
7066 {"SC_PII_XTI", _SC_PII_XTI},
7067#endif
7068#ifdef _SC_POLL
7069 {"SC_POLL", _SC_POLL},
7070#endif
7071#ifdef _SC_PRIORITIZED_IO
7072 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7073#endif
7074#ifdef _SC_PRIORITY_SCHEDULING
7075 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7076#endif
7077#ifdef _SC_REALTIME_SIGNALS
7078 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7079#endif
7080#ifdef _SC_RE_DUP_MAX
7081 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7082#endif
7083#ifdef _SC_RTSIG_MAX
7084 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7085#endif
7086#ifdef _SC_SAVED_IDS
7087 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7088#endif
7089#ifdef _SC_SCHAR_MAX
7090 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7091#endif
7092#ifdef _SC_SCHAR_MIN
7093 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7094#endif
7095#ifdef _SC_SELECT
7096 {"SC_SELECT", _SC_SELECT},
7097#endif
7098#ifdef _SC_SEMAPHORES
7099 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7100#endif
7101#ifdef _SC_SEM_NSEMS_MAX
7102 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7103#endif
7104#ifdef _SC_SEM_VALUE_MAX
7105 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7106#endif
7107#ifdef _SC_SHARED_MEMORY_OBJECTS
7108 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7109#endif
7110#ifdef _SC_SHRT_MAX
7111 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7112#endif
7113#ifdef _SC_SHRT_MIN
7114 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7115#endif
7116#ifdef _SC_SIGQUEUE_MAX
7117 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7118#endif
7119#ifdef _SC_SIGRT_MAX
7120 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7121#endif
7122#ifdef _SC_SIGRT_MIN
7123 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7124#endif
Fred Draked86ed291999-12-15 15:34:33 +00007125#ifdef _SC_SOFTPOWER
7126 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7127#endif
Fred Drakec9680921999-12-13 16:37:25 +00007128#ifdef _SC_SPLIT_CACHE
7129 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7130#endif
7131#ifdef _SC_SSIZE_MAX
7132 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7133#endif
7134#ifdef _SC_STACK_PROT
7135 {"SC_STACK_PROT", _SC_STACK_PROT},
7136#endif
7137#ifdef _SC_STREAM_MAX
7138 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7139#endif
7140#ifdef _SC_SYNCHRONIZED_IO
7141 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7142#endif
7143#ifdef _SC_THREADS
7144 {"SC_THREADS", _SC_THREADS},
7145#endif
7146#ifdef _SC_THREAD_ATTR_STACKADDR
7147 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7148#endif
7149#ifdef _SC_THREAD_ATTR_STACKSIZE
7150 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7151#endif
7152#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7153 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7154#endif
7155#ifdef _SC_THREAD_KEYS_MAX
7156 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7157#endif
7158#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7159 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7160#endif
7161#ifdef _SC_THREAD_PRIO_INHERIT
7162 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7163#endif
7164#ifdef _SC_THREAD_PRIO_PROTECT
7165 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7166#endif
7167#ifdef _SC_THREAD_PROCESS_SHARED
7168 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7169#endif
7170#ifdef _SC_THREAD_SAFE_FUNCTIONS
7171 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7172#endif
7173#ifdef _SC_THREAD_STACK_MIN
7174 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7175#endif
7176#ifdef _SC_THREAD_THREADS_MAX
7177 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7178#endif
7179#ifdef _SC_TIMERS
7180 {"SC_TIMERS", _SC_TIMERS},
7181#endif
7182#ifdef _SC_TIMER_MAX
7183 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7184#endif
7185#ifdef _SC_TTY_NAME_MAX
7186 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7187#endif
7188#ifdef _SC_TZNAME_MAX
7189 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7190#endif
7191#ifdef _SC_T_IOV_MAX
7192 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7193#endif
7194#ifdef _SC_UCHAR_MAX
7195 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7196#endif
7197#ifdef _SC_UINT_MAX
7198 {"SC_UINT_MAX", _SC_UINT_MAX},
7199#endif
7200#ifdef _SC_UIO_MAXIOV
7201 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7202#endif
7203#ifdef _SC_ULONG_MAX
7204 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7205#endif
7206#ifdef _SC_USHRT_MAX
7207 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7208#endif
7209#ifdef _SC_VERSION
7210 {"SC_VERSION", _SC_VERSION},
7211#endif
7212#ifdef _SC_WORD_BIT
7213 {"SC_WORD_BIT", _SC_WORD_BIT},
7214#endif
7215#ifdef _SC_XBS5_ILP32_OFF32
7216 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7217#endif
7218#ifdef _SC_XBS5_ILP32_OFFBIG
7219 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7220#endif
7221#ifdef _SC_XBS5_LP64_OFF64
7222 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7223#endif
7224#ifdef _SC_XBS5_LPBIG_OFFBIG
7225 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7226#endif
7227#ifdef _SC_XOPEN_CRYPT
7228 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7229#endif
7230#ifdef _SC_XOPEN_ENH_I18N
7231 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7232#endif
7233#ifdef _SC_XOPEN_LEGACY
7234 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7235#endif
7236#ifdef _SC_XOPEN_REALTIME
7237 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7238#endif
7239#ifdef _SC_XOPEN_REALTIME_THREADS
7240 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7241#endif
7242#ifdef _SC_XOPEN_SHM
7243 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7244#endif
7245#ifdef _SC_XOPEN_UNIX
7246 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7247#endif
7248#ifdef _SC_XOPEN_VERSION
7249 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7250#endif
7251#ifdef _SC_XOPEN_XCU_VERSION
7252 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7253#endif
7254#ifdef _SC_XOPEN_XPG2
7255 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7256#endif
7257#ifdef _SC_XOPEN_XPG3
7258 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7259#endif
7260#ifdef _SC_XOPEN_XPG4
7261 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7262#endif
7263};
7264
7265static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007266conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007267{
7268 return conv_confname(arg, valuep, posix_constants_sysconf,
7269 sizeof(posix_constants_sysconf)
7270 / sizeof(struct constdef));
7271}
7272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007273PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007274"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007275Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007276
7277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007278posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007279{
7280 PyObject *result = NULL;
7281 int name;
7282
7283 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7284 int value;
7285
7286 errno = 0;
7287 value = sysconf(name);
7288 if (value == -1 && errno != 0)
7289 posix_error();
7290 else
7291 result = PyInt_FromLong(value);
7292 }
7293 return result;
7294}
7295#endif
7296
7297
Fred Drakebec628d1999-12-15 18:31:10 +00007298/* This code is used to ensure that the tables of configuration value names
7299 * are in sorted order as required by conv_confname(), and also to build the
7300 * the exported dictionaries that are used to publish information about the
7301 * names available on the host platform.
7302 *
7303 * Sorting the table at runtime ensures that the table is properly ordered
7304 * when used, even for platforms we're not able to test on. It also makes
7305 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007306 */
Fred Drakebec628d1999-12-15 18:31:10 +00007307
7308static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007309cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007310{
7311 const struct constdef *c1 =
7312 (const struct constdef *) v1;
7313 const struct constdef *c2 =
7314 (const struct constdef *) v2;
7315
7316 return strcmp(c1->name, c2->name);
7317}
7318
7319static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007320setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007321 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007322{
Fred Drakebec628d1999-12-15 18:31:10 +00007323 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007324 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007325
7326 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7327 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007328 if (d == NULL)
7329 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007330
Barry Warsaw3155db32000-04-13 15:20:40 +00007331 for (i=0; i < tablesize; ++i) {
7332 PyObject *o = PyInt_FromLong(table[i].value);
7333 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7334 Py_XDECREF(o);
7335 Py_DECREF(d);
7336 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007337 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007338 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007339 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007340 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007341}
7342
Fred Drakebec628d1999-12-15 18:31:10 +00007343/* Return -1 on failure, 0 on success. */
7344static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007345setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007346{
7347#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007348 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007349 sizeof(posix_constants_pathconf)
7350 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007351 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007352 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007353#endif
7354#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007355 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007356 sizeof(posix_constants_confstr)
7357 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007358 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007359 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007360#endif
7361#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007362 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007363 sizeof(posix_constants_sysconf)
7364 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007365 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007366 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007367#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007368 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007369}
Fred Draked86ed291999-12-15 15:34:33 +00007370
7371
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007372PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007373"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007374Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007375in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007376
7377static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007378posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007379{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007380 abort();
7381 /*NOTREACHED*/
7382 Py_FatalError("abort() called from Python code didn't abort!");
7383 return NULL;
7384}
Fred Drakebec628d1999-12-15 18:31:10 +00007385
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007386#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007387PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007388"startfile(filepath [, operation]) - Start a file with its associated\n\
7389application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007390\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007391When \"operation\" is not specified or \"open\", this acts like\n\
7392double-clicking the file in Explorer, or giving the file name as an\n\
7393argument to the DOS \"start\" command: the file is opened with whatever\n\
7394application (if any) its extension is associated.\n\
7395When another \"operation\" is given, it specifies what should be done with\n\
7396the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007397\n\
7398startfile returns as soon as the associated application is launched.\n\
7399There is no option to wait for the application to close, and no way\n\
7400to retrieve the application's exit status.\n\
7401\n\
7402The filepath is relative to the current directory. If you want to use\n\
7403an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007404the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007405
7406static PyObject *
7407win32_startfile(PyObject *self, PyObject *args)
7408{
7409 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007410 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007411 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007412 if (!PyArg_ParseTuple(args, "et|s:startfile",
7413 Py_FileSystemDefaultEncoding, &filepath,
7414 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007415 return NULL;
7416 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007417 rc = ShellExecute((HWND)0, operation, filepath,
7418 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007419 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007420 if (rc <= (HINSTANCE)32) {
7421 PyObject *errval = win32_error("startfile", filepath);
7422 PyMem_Free(filepath);
7423 return errval;
7424 }
7425 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007426 Py_INCREF(Py_None);
7427 return Py_None;
7428}
7429#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007430
Martin v. Löwis438b5342002-12-27 10:16:42 +00007431#ifdef HAVE_GETLOADAVG
7432PyDoc_STRVAR(posix_getloadavg__doc__,
7433"getloadavg() -> (float, float, float)\n\n\
7434Return the number of processes in the system run queue averaged over\n\
7435the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7436was unobtainable");
7437
7438static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007439posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007440{
7441 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007442 if (getloadavg(loadavg, 3)!=3) {
7443 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7444 return NULL;
7445 } else
7446 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7447}
7448#endif
7449
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007450#ifdef MS_WINDOWS
7451
7452PyDoc_STRVAR(win32_urandom__doc__,
7453"urandom(n) -> str\n\n\
7454Return a string of n random bytes suitable for cryptographic use.");
7455
7456typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7457 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7458 DWORD dwFlags );
7459typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7460 BYTE *pbBuffer );
7461
7462static CRYPTGENRANDOM pCryptGenRandom = NULL;
7463static HCRYPTPROV hCryptProv = 0;
7464
Tim Peters4ad82172004-08-30 17:02:04 +00007465static PyObject*
7466win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007467{
Tim Petersd3115382004-08-30 17:36:46 +00007468 int howMany;
7469 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007470
Tim Peters4ad82172004-08-30 17:02:04 +00007471 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007472 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007473 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007474 if (howMany < 0)
7475 return PyErr_Format(PyExc_ValueError,
7476 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007477
Tim Peters4ad82172004-08-30 17:02:04 +00007478 if (hCryptProv == 0) {
7479 HINSTANCE hAdvAPI32 = NULL;
7480 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007481
Tim Peters4ad82172004-08-30 17:02:04 +00007482 /* Obtain handle to the DLL containing CryptoAPI
7483 This should not fail */
7484 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7485 if(hAdvAPI32 == NULL)
7486 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007487
Tim Peters4ad82172004-08-30 17:02:04 +00007488 /* Obtain pointers to the CryptoAPI functions
7489 This will fail on some early versions of Win95 */
7490 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7491 hAdvAPI32,
7492 "CryptAcquireContextA");
7493 if (pCryptAcquireContext == NULL)
7494 return PyErr_Format(PyExc_NotImplementedError,
7495 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007496
Tim Peters4ad82172004-08-30 17:02:04 +00007497 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7498 hAdvAPI32, "CryptGenRandom");
7499 if (pCryptAcquireContext == NULL)
7500 return PyErr_Format(PyExc_NotImplementedError,
7501 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007502
Tim Peters4ad82172004-08-30 17:02:04 +00007503 /* Acquire context */
7504 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7505 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7506 return win32_error("CryptAcquireContext", NULL);
7507 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007508
Tim Peters4ad82172004-08-30 17:02:04 +00007509 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007510 result = PyString_FromStringAndSize(NULL, howMany);
7511 if (result != NULL) {
7512 /* Get random data */
7513 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7514 PyString_AS_STRING(result))) {
7515 Py_DECREF(result);
7516 return win32_error("CryptGenRandom", NULL);
7517 }
Tim Peters4ad82172004-08-30 17:02:04 +00007518 }
Tim Petersd3115382004-08-30 17:36:46 +00007519 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007520}
7521#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007522
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007523static PyMethodDef posix_methods[] = {
7524 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7525#ifdef HAVE_TTYNAME
7526 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7527#endif
7528 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7529 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007530#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007531 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007532#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007533#ifdef HAVE_LCHOWN
7534 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7535#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007536#ifdef HAVE_CHROOT
7537 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7538#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007539#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007540 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007541#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007542#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007543 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007544#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007545 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007546#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007547#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007548#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007549 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007550#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007551 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7552 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7553 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007554#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007556#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007557#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007558 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007559#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7561 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7562 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007563 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007564#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007566#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007567#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007568 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007569#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007571#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007572 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007573#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7575 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7576 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007577#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007578 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007579#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007580 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007581#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007582 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7583 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007584#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007585#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007586 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7587 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007588#if defined(PYOS_OS2)
7589 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7590 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7591#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007592#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007593#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007594 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007595#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007596#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007597 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007598#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007599#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007600 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007601#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007602#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007603 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007604#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007605#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007606 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007607#endif /* HAVE_GETEGID */
7608#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007609 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007610#endif /* HAVE_GETEUID */
7611#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007612 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007613#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007614#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007615 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007616#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007617 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007618#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007619 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007620#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007621#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007622 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007623#endif /* HAVE_GETPPID */
7624#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007625 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007626#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007627#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007628 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007629#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007630#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007632#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007633#ifdef HAVE_KILLPG
7634 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7635#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007636#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007637 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007638#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007639#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007640 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007641#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007642 {"popen2", win32_popen2, METH_VARARGS},
7643 {"popen3", win32_popen3, METH_VARARGS},
7644 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007645 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007646#else
7647#if defined(PYOS_OS2) && defined(PYCC_GCC)
7648 {"popen2", os2emx_popen2, METH_VARARGS},
7649 {"popen3", os2emx_popen3, METH_VARARGS},
7650 {"popen4", os2emx_popen4, METH_VARARGS},
7651#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007652#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007653#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007655 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007656#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007657#ifdef HAVE_SETEUID
7658 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7659#endif /* HAVE_SETEUID */
7660#ifdef HAVE_SETEGID
7661 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7662#endif /* HAVE_SETEGID */
7663#ifdef HAVE_SETREUID
7664 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7665#endif /* HAVE_SETREUID */
7666#ifdef HAVE_SETREGID
7667 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7668#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007669#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007670 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007671#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007672#ifdef HAVE_SETGROUPS
7673 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7674#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007675#ifdef HAVE_GETPGID
7676 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7677#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007678#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007679 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007680#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007681#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007682 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007683#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007684#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007685 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007686#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007687#ifdef HAVE_GETSID
7688 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7689#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007690#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007691 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007692#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007693#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007694 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007695#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007696#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007697 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007698#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007699#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007700 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007701#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007702 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7703 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7704 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7705 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7706 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7707 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7708 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7709 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7710 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007711 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007712#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007713 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007714#endif
7715#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007716 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007717#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007718#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007719 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7720#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007721#ifdef HAVE_DEVICE_MACROS
7722 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7723 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7724 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7725#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007726#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007727 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007728#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007729#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007730 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007731#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007732#ifdef HAVE_UNSETENV
7733 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7734#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007735#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007736 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007737#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007738#ifdef HAVE_FCHDIR
7739 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7740#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007741#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007742 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007743#endif
7744#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007745 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007746#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007747#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007748#ifdef WCOREDUMP
7749 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7750#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007751#ifdef WIFCONTINUED
7752 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7753#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007754#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007755 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007756#endif /* WIFSTOPPED */
7757#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007758 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007759#endif /* WIFSIGNALED */
7760#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007761 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007762#endif /* WIFEXITED */
7763#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007764 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007765#endif /* WEXITSTATUS */
7766#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007767 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007768#endif /* WTERMSIG */
7769#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007770 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007771#endif /* WSTOPSIG */
7772#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007773#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007774 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007775#endif
7776#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007777 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007778#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007779#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007780 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007781#endif
7782#ifdef HAVE_TEMPNAM
7783 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7784#endif
7785#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007786 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007787#endif
Fred Drakec9680921999-12-13 16:37:25 +00007788#ifdef HAVE_CONFSTR
7789 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7790#endif
7791#ifdef HAVE_SYSCONF
7792 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7793#endif
7794#ifdef HAVE_FPATHCONF
7795 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7796#endif
7797#ifdef HAVE_PATHCONF
7798 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7799#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007800 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007801#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007802 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7803#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007804#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007805 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007806#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007807 #ifdef MS_WINDOWS
7808 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7809 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007810 {NULL, NULL} /* Sentinel */
7811};
7812
7813
Barry Warsaw4a342091996-12-19 23:50:02 +00007814static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007815ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007816{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007817 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007818}
7819
Guido van Rossumd48f2521997-12-05 22:19:34 +00007820#if defined(PYOS_OS2)
7821/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007822static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007823{
7824 APIRET rc;
7825 ULONG values[QSV_MAX+1];
7826 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007827 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007828
7829 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007830 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007831 Py_END_ALLOW_THREADS
7832
7833 if (rc != NO_ERROR) {
7834 os2_error(rc);
7835 return -1;
7836 }
7837
Fred Drake4d1e64b2002-04-15 19:40:07 +00007838 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7839 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7840 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7841 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7842 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7843 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7844 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007845
7846 switch (values[QSV_VERSION_MINOR]) {
7847 case 0: ver = "2.00"; break;
7848 case 10: ver = "2.10"; break;
7849 case 11: ver = "2.11"; break;
7850 case 30: ver = "3.00"; break;
7851 case 40: ver = "4.00"; break;
7852 case 50: ver = "5.00"; break;
7853 default:
Tim Peters885d4572001-11-28 20:27:42 +00007854 PyOS_snprintf(tmp, sizeof(tmp),
7855 "%d-%d", values[QSV_VERSION_MAJOR],
7856 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007857 ver = &tmp[0];
7858 }
7859
7860 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007861 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007862 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007863
7864 /* Add Indicator of Which Drive was Used to Boot the System */
7865 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7866 tmp[1] = ':';
7867 tmp[2] = '\0';
7868
Fred Drake4d1e64b2002-04-15 19:40:07 +00007869 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007870}
7871#endif
7872
Barry Warsaw4a342091996-12-19 23:50:02 +00007873static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007874all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007875{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007876#ifdef F_OK
7877 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007878#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007879#ifdef R_OK
7880 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007881#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007882#ifdef W_OK
7883 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007884#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007885#ifdef X_OK
7886 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007887#endif
Fred Drakec9680921999-12-13 16:37:25 +00007888#ifdef NGROUPS_MAX
7889 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7890#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007891#ifdef TMP_MAX
7892 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7893#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007894#ifdef WCONTINUED
7895 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7896#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007897#ifdef WNOHANG
7898 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007899#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007900#ifdef WUNTRACED
7901 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7902#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007903#ifdef O_RDONLY
7904 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7905#endif
7906#ifdef O_WRONLY
7907 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7908#endif
7909#ifdef O_RDWR
7910 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7911#endif
7912#ifdef O_NDELAY
7913 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7914#endif
7915#ifdef O_NONBLOCK
7916 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7917#endif
7918#ifdef O_APPEND
7919 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7920#endif
7921#ifdef O_DSYNC
7922 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7923#endif
7924#ifdef O_RSYNC
7925 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7926#endif
7927#ifdef O_SYNC
7928 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7929#endif
7930#ifdef O_NOCTTY
7931 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7932#endif
7933#ifdef O_CREAT
7934 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7935#endif
7936#ifdef O_EXCL
7937 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7938#endif
7939#ifdef O_TRUNC
7940 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7941#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007942#ifdef O_BINARY
7943 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7944#endif
7945#ifdef O_TEXT
7946 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7947#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007948#ifdef O_LARGEFILE
7949 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7950#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007951#ifdef O_SHLOCK
7952 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7953#endif
7954#ifdef O_EXLOCK
7955 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7956#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007957
Tim Peters5aa91602002-01-30 05:46:57 +00007958/* MS Windows */
7959#ifdef O_NOINHERIT
7960 /* Don't inherit in child processes. */
7961 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7962#endif
7963#ifdef _O_SHORT_LIVED
7964 /* Optimize for short life (keep in memory). */
7965 /* MS forgot to define this one with a non-underscore form too. */
7966 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7967#endif
7968#ifdef O_TEMPORARY
7969 /* Automatically delete when last handle is closed. */
7970 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7971#endif
7972#ifdef O_RANDOM
7973 /* Optimize for random access. */
7974 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7975#endif
7976#ifdef O_SEQUENTIAL
7977 /* Optimize for sequential access. */
7978 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7979#endif
7980
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007981/* GNU extensions. */
7982#ifdef O_DIRECT
7983 /* Direct disk access. */
7984 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7985#endif
7986#ifdef O_DIRECTORY
7987 /* Must be a directory. */
7988 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7989#endif
7990#ifdef O_NOFOLLOW
7991 /* Do not follow links. */
7992 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7993#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007994
Barry Warsaw5676bd12003-01-07 20:57:09 +00007995 /* These come from sysexits.h */
7996#ifdef EX_OK
7997 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007998#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007999#ifdef EX_USAGE
8000 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008001#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008002#ifdef EX_DATAERR
8003 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008004#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008005#ifdef EX_NOINPUT
8006 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008007#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008008#ifdef EX_NOUSER
8009 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008010#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008011#ifdef EX_NOHOST
8012 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008013#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008014#ifdef EX_UNAVAILABLE
8015 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008016#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008017#ifdef EX_SOFTWARE
8018 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008019#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008020#ifdef EX_OSERR
8021 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008022#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008023#ifdef EX_OSFILE
8024 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008025#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008026#ifdef EX_CANTCREAT
8027 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008028#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008029#ifdef EX_IOERR
8030 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008031#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008032#ifdef EX_TEMPFAIL
8033 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008034#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008035#ifdef EX_PROTOCOL
8036 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008037#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008038#ifdef EX_NOPERM
8039 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008040#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008041#ifdef EX_CONFIG
8042 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008043#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008044#ifdef EX_NOTFOUND
8045 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008046#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008047
Guido van Rossum246bc171999-02-01 23:54:31 +00008048#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008049#if defined(PYOS_OS2) && defined(PYCC_GCC)
8050 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8051 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8052 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8053 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8054 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8055 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8056 if (ins(d, "P_PM", (long)P_PM)) return -1;
8057 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8058 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8059 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8060 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8061 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8062 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8063 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8064 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8065 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8066 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8067 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8068 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8069 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8070#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008071 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8072 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8073 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8074 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8075 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008076#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008077#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008078
Guido van Rossumd48f2521997-12-05 22:19:34 +00008079#if defined(PYOS_OS2)
8080 if (insertvalues(d)) return -1;
8081#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008082 return 0;
8083}
8084
8085
Tim Peters5aa91602002-01-30 05:46:57 +00008086#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008087#define INITFUNC initnt
8088#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008089
8090#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008091#define INITFUNC initos2
8092#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008093
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008094#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008095#define INITFUNC initposix
8096#define MODNAME "posix"
8097#endif
8098
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008099PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008100INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008101{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008102 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008103
Fred Drake4d1e64b2002-04-15 19:40:07 +00008104 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008105 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008106 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008107 if (m == NULL)
8108 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008109
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008110 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008111 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008112 Py_XINCREF(v);
8113 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008114 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008115 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008116
Fred Drake4d1e64b2002-04-15 19:40:07 +00008117 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008118 return;
8119
Fred Drake4d1e64b2002-04-15 19:40:07 +00008120 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008121 return;
8122
Fred Drake4d1e64b2002-04-15 19:40:07 +00008123 Py_INCREF(PyExc_OSError);
8124 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008125
Guido van Rossumb3d39562000-01-31 18:41:26 +00008126#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008127 if (posix_putenv_garbage == NULL)
8128 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008129#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008130
Guido van Rossum14648392001-12-08 18:02:58 +00008131 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008132 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8133 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8134 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008135 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008136 structseq_new = StatResultType.tp_new;
8137 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008138 Py_INCREF((PyObject*) &StatResultType);
8139 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008140
Guido van Rossum14648392001-12-08 18:02:58 +00008141 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008142 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008143 Py_INCREF((PyObject*) &StatVFSResultType);
8144 PyModule_AddObject(m, "statvfs_result",
8145 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008146}