blob: 12e1c837005a651dbbdea02ad0191960a6931752 [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
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
68#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000069
Guido van Rossum36bc6801995-06-14 22:54:23 +000070#ifdef HAVE_SYS_WAIT_H
71#include <sys/wait.h> /* For WNOHANG */
72#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000073
Guido van Rossuma376cc51996-12-05 23:43:35 +000074#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000075
Guido van Rossumb6775db1994-08-01 11:34:53 +000076#ifdef HAVE_FCNTL_H
77#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000078#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000079
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080#ifdef HAVE_GRP_H
81#include <grp.h>
82#endif
83
Barry Warsaw5676bd12003-01-07 20:57:09 +000084#ifdef HAVE_SYSEXITS_H
85#include <sysexits.h>
86#endif /* HAVE_SYSEXITS_H */
87
Anthony Baxter8a560de2004-10-13 15:30:56 +000088#ifdef HAVE_SYS_LOADAVG_H
89#include <sys/loadavg.h>
90#endif
91
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000093/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000094#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000095#include <process.h>
96#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000097#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000098#define HAVE_GETCWD 1
99#define HAVE_OPENDIR 1
100#define HAVE_SYSTEM 1
101#if defined(__OS2__)
102#define HAVE_EXECV 1
103#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000104#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#include <process.h>
106#else
107#ifdef __BORLANDC__ /* Borland compiler */
108#define HAVE_EXECV 1
109#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#define HAVE_OPENDIR 1
111#define HAVE_PIPE 1
112#define HAVE_POPEN 1
113#define HAVE_SYSTEM 1
114#define HAVE_WAIT 1
115#else
116#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000117#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000118#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_EXECV 1
120#define HAVE_PIPE 1
121#define HAVE_POPEN 1
122#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000123#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000124#define HAVE_FSYNC 1
125#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000126#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000127#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
128/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000129#else /* all other compilers */
130/* Unix functions that the configure script doesn't check for */
131#define HAVE_EXECV 1
132#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000133#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
134#define HAVE_FORK1 1
135#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#define HAVE_GETCWD 1
137#define HAVE_GETEGID 1
138#define HAVE_GETEUID 1
139#define HAVE_GETGID 1
140#define HAVE_GETPPID 1
141#define HAVE_GETUID 1
142#define HAVE_KILL 1
143#define HAVE_OPENDIR 1
144#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000145#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000147#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148#define HAVE_SYSTEM 1
149#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000150#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000151#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#endif /* _MSC_VER */
153#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000154#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000155#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000158
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000159#if defined(__sgi)&&_COMPILER_VERSION>=700
160/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
161 (default) */
162extern char *ctermid_r(char *);
163#endif
164
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000165#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000166#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000169#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000174#endif
175#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int chdir(char *);
177extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(const char *);
180extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000182#ifdef __BORLANDC__
183extern int chmod(const char *, int);
184#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000185extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000186#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chown(const char *, uid_t, gid_t);
188extern char *getcwd(char *, int);
189extern char *strerror(int);
190extern int link(const char *, const char *);
191extern int rename(const char *, const char *);
192extern int stat(const char *, struct stat *);
193extern int unlink(const char *);
194extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000197#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000202
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_UTIME_H
206#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000209#ifdef HAVE_SYS_UTIME_H
210#include <sys/utime.h>
211#define HAVE_UTIME_H /* pretend we do for the rest of this file */
212#endif /* HAVE_SYS_UTIME_H */
213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_SYS_TIMES_H
215#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
218#ifdef HAVE_SYS_PARAM_H
219#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
222#ifdef HAVE_SYS_UTSNAME_H
223#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000224#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000228#define NAMLEN(dirent) strlen((dirent)->d_name)
229#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000230#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#include <direct.h>
232#define NAMLEN(dirent) strlen((dirent)->d_name)
233#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#endif
246#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000248#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <direct.h>
250#include <io.h>
251#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000252#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000253#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000255#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000256#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000257#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000258#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
Guido van Rossumd48f2521997-12-05 22:19:34 +0000260#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263
Tim Petersbc2e10e2002-03-03 23:17:02 +0000264#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000265#if defined(PATH_MAX) && PATH_MAX > 1024
266#define MAXPATHLEN PATH_MAX
267#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000268#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000269#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000270#endif /* MAXPATHLEN */
271
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000272#ifdef UNION_WAIT
273/* Emulate some macros on systems that have a union instead of macros */
274
275#ifndef WIFEXITED
276#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
277#endif
278
279#ifndef WEXITSTATUS
280#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
281#endif
282
283#ifndef WTERMSIG
284#define WTERMSIG(u_wait) ((u_wait).w_termsig)
285#endif
286
Neal Norwitzd5a37542006-03-20 06:48:34 +0000287#define WAIT_TYPE union wait
288#define WAIT_STATUS_INT(s) (s.w_status)
289
290#else /* !UNION_WAIT */
291#define WAIT_TYPE int
292#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#endif /* UNION_WAIT */
294
Greg Wardb48bc172000-03-01 21:51:56 +0000295/* Don't use the "_r" form if we don't need it (also, won't have a
296 prototype for it, at least on Solaris -- maybe others as well?). */
297#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
298#define USE_CTERMID_R
299#endif
300
301#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
302#define USE_TMPNAM_R
303#endif
304
Fred Drake699f3522000-06-29 21:12:41 +0000305/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000306#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000307#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000308# define STAT win32_stat
309# define FSTAT win32_fstat
310# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000311#else
312# define STAT stat
313# define FSTAT fstat
314# define STRUCT_STAT struct stat
315#endif
316
Tim Peters11b23062003-04-23 02:39:17 +0000317#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000318#include <sys/mkdev.h>
319#else
320#if defined(MAJOR_IN_SYSMACROS)
321#include <sys/sysmacros.h>
322#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000323#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
324#include <sys/mkdev.h>
325#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#endif
Fred Drake699f3522000-06-29 21:12:41 +0000327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000329#ifdef WITH_NEXT_FRAMEWORK
330/* On Darwin/MacOSX a shared library or framework has no access to
331** environ directly, we must obtain it with _NSGetEnviron().
332*/
333#include <crt_externs.h>
334static char **environ;
335#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Barry Warsaw53699e91996-12-10 23:23:01 +0000339static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000340convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Barry Warsaw53699e91996-12-10 23:23:01 +0000342 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000344 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 if (d == NULL)
346 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348 if (environ == NULL)
349 environ = *_NSGetEnviron();
350#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 if (environ == NULL)
352 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000353 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000355 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000356 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 char *p = strchr(*e, '=');
358 if (p == NULL)
359 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000360 k = PyString_FromStringAndSize(*e, (int)(p-*e));
361 if (k == NULL) {
362 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000364 }
365 v = PyString_FromString(p+1);
366 if (v == NULL) {
367 PyErr_Clear();
368 Py_DECREF(k);
369 continue;
370 }
371 if (PyDict_GetItem(d, k) == NULL) {
372 if (PyDict_SetItem(d, k, v) != 0)
373 PyErr_Clear();
374 }
375 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000376 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000378#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000379 {
380 APIRET rc;
381 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
382
383 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000384 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000385 PyObject *v = PyString_FromString(buffer);
386 PyDict_SetItemString(d, "BEGINLIBPATH", v);
387 Py_DECREF(v);
388 }
389 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
390 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
391 PyObject *v = PyString_FromString(buffer);
392 PyDict_SetItemString(d, "ENDLIBPATH", v);
393 Py_DECREF(v);
394 }
395 }
396#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return d;
398}
399
400
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401/* Set a POSIX-specific error from errno, and return NULL */
402
Barry Warsawd58d7641998-07-23 16:14:40 +0000403static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000404posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000405{
Barry Warsawca74da41999-02-09 19:31:45 +0000406 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407}
Barry Warsawd58d7641998-07-23 16:14:40 +0000408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000409posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000410{
Barry Warsawca74da41999-02-09 19:31:45 +0000411 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000412}
413
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000414#ifdef Py_WIN_WIDE_FILENAMES
415static PyObject *
416posix_error_with_unicode_filename(Py_UNICODE* name)
417{
418 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
419}
420#endif /* Py_WIN_WIDE_FILENAMES */
421
422
Mark Hammondef8b6542001-05-13 08:04:26 +0000423static PyObject *
424posix_error_with_allocated_filename(char* name)
425{
426 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
427 PyMem_Free(name);
428 return rc;
429}
430
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000431#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000432static PyObject *
433win32_error(char* function, char* filename)
434{
Mark Hammond33a6da92000-08-15 00:46:38 +0000435 /* XXX We should pass the function name along in the future.
436 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000437 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000438 Windows error object, which is non-trivial.
439 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000440 errno = GetLastError();
441 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000442 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000443 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000444 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000446
447#ifdef Py_WIN_WIDE_FILENAMES
448static PyObject *
449win32_error_unicode(char* function, Py_UNICODE* filename)
450{
451 /* XXX - see win32_error for comments on 'function' */
452 errno = GetLastError();
453 if (filename)
454 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
455 else
456 return PyErr_SetFromWindowsErr(errno);
457}
458
459static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
460{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000461}
462
463/* Function suitable for O& conversion */
464static int
465convert_to_unicode(PyObject *arg, void* _param)
466{
467 PyObject **param = (PyObject**)_param;
468 if (PyUnicode_CheckExact(arg)) {
469 Py_INCREF(arg);
470 *param = arg;
471 }
472 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000473 /* For a Unicode subtype that's not a Unicode object,
474 return a true Unicode object with the same data. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000475 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
476 PyUnicode_GET_SIZE(arg));
477 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000478 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479 else
480 *param = PyUnicode_FromEncodedObject(arg,
481 Py_FileSystemDefaultEncoding,
482 "strict");
483 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000484}
485
486#endif /* Py_WIN_WIDE_FILENAMES */
487
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000488#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489
Guido van Rossumd48f2521997-12-05 22:19:34 +0000490#if defined(PYOS_OS2)
491/**********************************************************************
492 * Helper Function to Trim and Format OS/2 Messages
493 **********************************************************************/
494 static void
495os2_formatmsg(char *msgbuf, int msglen, char *reason)
496{
497 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
498
499 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
500 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
501
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000502 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
504 }
505
506 /* Add Optional Reason Text */
507 if (reason) {
508 strcat(msgbuf, " : ");
509 strcat(msgbuf, reason);
510 }
511}
512
513/**********************************************************************
514 * Decode an OS/2 Operating System Error Code
515 *
516 * A convenience function to lookup an OS/2 error code and return a
517 * text message we can use to raise a Python exception.
518 *
519 * Notes:
520 * The messages for errors returned from the OS/2 kernel reside in
521 * the file OSO001.MSG in the \OS2 directory hierarchy.
522 *
523 **********************************************************************/
524 static char *
525os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
526{
527 APIRET rc;
528 ULONG msglen;
529
530 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
531 Py_BEGIN_ALLOW_THREADS
532 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
533 errorcode, "oso001.msg", &msglen);
534 Py_END_ALLOW_THREADS
535
536 if (rc == NO_ERROR)
537 os2_formatmsg(msgbuf, msglen, reason);
538 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000539 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000540 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000541
542 return msgbuf;
543}
544
545/* Set an OS/2-specific error and return NULL. OS/2 kernel
546 errors are not in a global variable e.g. 'errno' nor are
547 they congruent with posix error numbers. */
548
549static PyObject * os2_error(int code)
550{
551 char text[1024];
552 PyObject *v;
553
554 os2_strerror(text, sizeof(text), code, "");
555
556 v = Py_BuildValue("(is)", code, text);
557 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000558 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000559 Py_DECREF(v);
560 }
561 return NULL; /* Signal to Python that an Exception is Pending */
562}
563
564#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565
566/* POSIX generic methods */
567
Barry Warsaw53699e91996-12-10 23:23:01 +0000568static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000569posix_fildes(PyObject *fdobj, int (*func)(int))
570{
571 int fd;
572 int res;
573 fd = PyObject_AsFileDescriptor(fdobj);
574 if (fd < 0)
575 return NULL;
576 Py_BEGIN_ALLOW_THREADS
577 res = (*func)(fd);
578 Py_END_ALLOW_THREADS
579 if (res < 0)
580 return posix_error();
581 Py_INCREF(Py_None);
582 return Py_None;
583}
Guido van Rossum21142a01999-01-08 21:05:37 +0000584
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000585#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000586static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000587unicode_file_names(void)
588{
589 static int canusewide = -1;
590 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000591 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592 the Windows NT family. */
593 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
594 }
595 return canusewide;
596}
597#endif
Tim Peters11b23062003-04-23 02:39:17 +0000598
Guido van Rossum21142a01999-01-08 21:05:37 +0000599static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000600posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601{
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000604 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000605 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000608 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000609 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000611 return posix_error_with_allocated_filename(path1);
612 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000613 Py_INCREF(Py_None);
614 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000615}
616
Barry Warsaw53699e91996-12-10 23:23:01 +0000617static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000618posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000619 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000620 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621{
Mark Hammondef8b6542001-05-13 08:04:26 +0000622 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000625 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000626 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000628 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000629 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000630 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000631 PyMem_Free(path1);
632 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000633 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000634 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_INCREF(Py_None);
637 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638}
639
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000640#ifdef Py_WIN_WIDE_FILENAMES
641static PyObject*
642win32_1str(PyObject* args, char* func,
643 char* format, BOOL (__stdcall *funcA)(LPCSTR),
644 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
645{
646 PyObject *uni;
647 char *ansi;
648 BOOL result;
649 if (unicode_file_names()) {
650 if (!PyArg_ParseTuple(args, wformat, &uni))
651 PyErr_Clear();
652 else {
653 Py_BEGIN_ALLOW_THREADS
654 result = funcW(PyUnicode_AsUnicode(uni));
655 Py_END_ALLOW_THREADS
656 if (!result)
657 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
658 Py_INCREF(Py_None);
659 return Py_None;
660 }
661 }
662 if (!PyArg_ParseTuple(args, format, &ansi))
663 return NULL;
664 Py_BEGIN_ALLOW_THREADS
665 result = funcA(ansi);
666 Py_END_ALLOW_THREADS
667 if (!result)
668 return win32_error(func, ansi);
669 Py_INCREF(Py_None);
670 return Py_None;
671
672}
673
674/* This is a reimplementation of the C library's chdir function,
675 but one that produces Win32 errors instead of DOS error codes.
676 chdir is essentially a wrapper around SetCurrentDirectory; however,
677 it also needs to set "magic" environment variables indicating
678 the per-drive current directory, which are of the form =<drive>: */
679BOOL __stdcall
680win32_chdir(LPCSTR path)
681{
682 char new_path[MAX_PATH+1];
683 int result;
684 char env[4] = "=x:";
685
686 if(!SetCurrentDirectoryA(path))
687 return FALSE;
688 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
689 if (!result)
690 return FALSE;
691 /* In the ANSI API, there should not be any paths longer
692 than MAX_PATH. */
693 assert(result <= MAX_PATH+1);
694 if (strncmp(new_path, "\\\\", 2) == 0 ||
695 strncmp(new_path, "//", 2) == 0)
696 /* UNC path, nothing to do. */
697 return TRUE;
698 env[1] = new_path[0];
699 return SetEnvironmentVariableA(env, new_path);
700}
701
702/* The Unicode version differs from the ANSI version
703 since the current directory might exceed MAX_PATH characters */
704BOOL __stdcall
705win32_wchdir(LPCWSTR path)
706{
707 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
708 int result;
709 wchar_t env[4] = L"=x:";
710
711 if(!SetCurrentDirectoryW(path))
712 return FALSE;
713 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
714 if (!result)
715 return FALSE;
716 if (result > MAX_PATH+1) {
717 new_path = malloc(result);
718 if (!new_path) {
719 SetLastError(ERROR_OUTOFMEMORY);
720 return FALSE;
721 }
722 }
723 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
724 wcsncmp(new_path, L"//", 2) == 0)
725 /* UNC path, nothing to do. */
726 return TRUE;
727 env[1] = new_path[0];
728 result = SetEnvironmentVariableW(env, new_path);
729 if (new_path != _new_path)
730 free(new_path);
731 return result;
732}
733#endif
734
Martin v. Löwis14694662006-02-03 12:54:16 +0000735#ifdef MS_WINDOWS
736/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
737 - time stamps are restricted to second resolution
738 - file modification times suffer from forth-and-back conversions between
739 UTC and local time
740 Therefore, we implement our own stat, based on the Win32 API directly.
741*/
742#define HAVE_STAT_NSEC 1
743
744struct win32_stat{
745 int st_dev;
746 __int64 st_ino;
747 unsigned short st_mode;
748 int st_nlink;
749 int st_uid;
750 int st_gid;
751 int st_rdev;
752 __int64 st_size;
753 int st_atime;
754 int st_atime_nsec;
755 int st_mtime;
756 int st_mtime_nsec;
757 int st_ctime;
758 int st_ctime_nsec;
759};
760
761static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
762
763static void
764FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
765{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000766 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
767 /* Cannot simply cast and dereference in_ptr,
768 since it might not be aligned properly */
769 __int64 in;
770 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000771 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
772 /* XXX Win32 supports time stamps past 2038; we currently don't */
773 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
774}
775
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000776static void
777time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
778{
779 /* XXX endianness */
780 __int64 out;
781 out = time_in + secs_between_epochs;
782 out = out * 10000000 + nsec_in;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000783 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000784}
785
Martin v. Löwis14694662006-02-03 12:54:16 +0000786/* Below, we *know* that ugo+r is 0444 */
787#if _S_IREAD != 0400
788#error Unsupported C library
789#endif
790static int
791attributes_to_mode(DWORD attr)
792{
793 int m = 0;
794 if (attr & FILE_ATTRIBUTE_DIRECTORY)
795 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
796 else
797 m |= _S_IFREG;
798 if (attr & FILE_ATTRIBUTE_READONLY)
799 m |= 0444;
800 else
801 m |= 0666;
802 return m;
803}
804
805static int
806attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
807{
808 memset(result, 0, sizeof(*result));
809 result->st_mode = attributes_to_mode(info->dwFileAttributes);
810 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
811 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
812 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
813 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
814
815 return 0;
816}
817
818static int
819win32_stat(const char* path, struct win32_stat *result)
820{
821 WIN32_FILE_ATTRIBUTE_DATA info;
822 int code;
823 char *dot;
824 /* XXX not supported on Win95 and NT 3.x */
825 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
826 /* Protocol violation: we explicitly clear errno, instead of
827 setting it to a POSIX error. Callers should use GetLastError. */
828 errno = 0;
829 return -1;
830 }
831 code = attribute_data_to_stat(&info, result);
832 if (code != 0)
833 return code;
834 /* Set S_IFEXEC if it is an .exe, .bat, ... */
835 dot = strrchr(path, '.');
836 if (dot) {
837 if (stricmp(dot, ".bat") == 0 ||
838 stricmp(dot, ".cmd") == 0 ||
839 stricmp(dot, ".exe") == 0 ||
840 stricmp(dot, ".com") == 0)
841 result->st_mode |= 0111;
842 }
843 return code;
844}
845
846static int
847win32_wstat(const wchar_t* path, struct win32_stat *result)
848{
849 int code;
850 const wchar_t *dot;
851 WIN32_FILE_ATTRIBUTE_DATA info;
852 /* XXX not supported on Win95 and NT 3.x */
853 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
854 /* Protocol violation: we explicitly clear errno, instead of
855 setting it to a POSIX error. Callers should use GetLastError. */
856 errno = 0;
857 return -1;
858 }
859 code = attribute_data_to_stat(&info, result);
860 if (code < 0)
861 return code;
862 /* Set IFEXEC if it is an .exe, .bat, ... */
863 dot = wcsrchr(path, '.');
864 if (dot) {
865 if (_wcsicmp(dot, L".bat") == 0 ||
866 _wcsicmp(dot, L".cmd") == 0 ||
867 _wcsicmp(dot, L".exe") == 0 ||
868 _wcsicmp(dot, L".com") == 0)
869 result->st_mode |= 0111;
870 }
871 return code;
872}
873
874static int
875win32_fstat(int file_number, struct win32_stat *result)
876{
877 BY_HANDLE_FILE_INFORMATION info;
878 HANDLE h;
879 int type;
880
881 h = (HANDLE)_get_osfhandle(file_number);
882
883 /* Protocol violation: we explicitly clear errno, instead of
884 setting it to a POSIX error. Callers should use GetLastError. */
885 errno = 0;
886
887 if (h == INVALID_HANDLE_VALUE) {
888 /* This is really a C library error (invalid file handle).
889 We set the Win32 error to the closes one matching. */
890 SetLastError(ERROR_INVALID_HANDLE);
891 return -1;
892 }
893 memset(result, 0, sizeof(*result));
894
895 type = GetFileType(h);
896 if (type == FILE_TYPE_UNKNOWN) {
897 DWORD error = GetLastError();
898 if (error != 0) {
899 return -1;
900 }
901 /* else: valid but unknown file */
902 }
903
904 if (type != FILE_TYPE_DISK) {
905 if (type == FILE_TYPE_CHAR)
906 result->st_mode = _S_IFCHR;
907 else if (type == FILE_TYPE_PIPE)
908 result->st_mode = _S_IFIFO;
909 return 0;
910 }
911
912 if (!GetFileInformationByHandle(h, &info)) {
913 return -1;
914 }
915
916 /* similar to stat() */
917 result->st_mode = attributes_to_mode(info.dwFileAttributes);
918 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
919 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
920 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
921 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
922 /* specific to fstat() */
923 result->st_nlink = info.nNumberOfLinks;
924 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
925 return 0;
926}
927
928#endif /* MS_WINDOWS */
929
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000930PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931"stat_result: Result from stat or lstat.\n\n\
932This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000933 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000934or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
935\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000936Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
937or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000939See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000940
941static PyStructSequence_Field stat_result_fields[] = {
942 {"st_mode", "protection bits"},
943 {"st_ino", "inode"},
944 {"st_dev", "device"},
945 {"st_nlink", "number of hard links"},
946 {"st_uid", "user ID of owner"},
947 {"st_gid", "group ID of owner"},
948 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000949 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
950 {NULL, "integer time of last access"},
951 {NULL, "integer time of last modification"},
952 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000953 {"st_atime", "time of last access"},
954 {"st_mtime", "time of last modification"},
955 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000956#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000957 {"st_blksize", "blocksize for filesystem I/O"},
958#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000959#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000960 {"st_blocks", "number of blocks allocated"},
961#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000962#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000963 {"st_rdev", "device type (if inode device)"},
964#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000965#ifdef HAVE_STRUCT_STAT_ST_FLAGS
966 {"st_flags", "user defined flags for file"},
967#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000968#ifdef HAVE_STRUCT_STAT_ST_GEN
969 {"st_gen", "generation number"},
970#endif
971#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
972 {"st_birthtime", "time of creation"},
973#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000974 {0}
975};
976
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000977#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000978#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000979#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000980#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000981#endif
982
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000983#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000984#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
985#else
986#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
987#endif
988
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000989#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000990#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
991#else
992#define ST_RDEV_IDX ST_BLOCKS_IDX
993#endif
994
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000995#ifdef HAVE_STRUCT_STAT_ST_FLAGS
996#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
997#else
998#define ST_FLAGS_IDX ST_RDEV_IDX
999#endif
1000
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001001#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001002#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001003#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001004#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001005#endif
1006
1007#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1008#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1009#else
1010#define ST_BIRTHTIME_IDX ST_GEN_IDX
1011#endif
1012
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001013static PyStructSequence_Desc stat_result_desc = {
1014 "stat_result", /* name */
1015 stat_result__doc__, /* doc */
1016 stat_result_fields,
1017 10
1018};
1019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001020PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001021"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1022This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001023 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001024or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001025\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001026See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001027
1028static PyStructSequence_Field statvfs_result_fields[] = {
1029 {"f_bsize", },
1030 {"f_frsize", },
1031 {"f_blocks", },
1032 {"f_bfree", },
1033 {"f_bavail", },
1034 {"f_files", },
1035 {"f_ffree", },
1036 {"f_favail", },
1037 {"f_flag", },
1038 {"f_namemax",},
1039 {0}
1040};
1041
1042static PyStructSequence_Desc statvfs_result_desc = {
1043 "statvfs_result", /* name */
1044 statvfs_result__doc__, /* doc */
1045 statvfs_result_fields,
1046 10
1047};
1048
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001049static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001050static PyTypeObject StatResultType;
1051static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001052static newfunc structseq_new;
1053
1054static PyObject *
1055statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1056{
1057 PyStructSequence *result;
1058 int i;
1059
1060 result = (PyStructSequence*)structseq_new(type, args, kwds);
1061 if (!result)
1062 return NULL;
1063 /* If we have been initialized from a tuple,
1064 st_?time might be set to None. Initialize it
1065 from the int slots. */
1066 for (i = 7; i <= 9; i++) {
1067 if (result->ob_item[i+3] == Py_None) {
1068 Py_DECREF(Py_None);
1069 Py_INCREF(result->ob_item[i]);
1070 result->ob_item[i+3] = result->ob_item[i];
1071 }
1072 }
1073 return (PyObject*)result;
1074}
1075
1076
1077
1078/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001079static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001080
1081PyDoc_STRVAR(stat_float_times__doc__,
1082"stat_float_times([newval]) -> oldval\n\n\
1083Determine whether os.[lf]stat represents time stamps as float objects.\n\
1084If newval is True, future calls to stat() return floats, if it is False,\n\
1085future calls return ints. \n\
1086If newval is omitted, return the current setting.\n");
1087
1088static PyObject*
1089stat_float_times(PyObject* self, PyObject *args)
1090{
1091 int newval = -1;
1092 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1093 return NULL;
1094 if (newval == -1)
1095 /* Return old value */
1096 return PyBool_FromLong(_stat_float_times);
1097 _stat_float_times = newval;
1098 Py_INCREF(Py_None);
1099 return Py_None;
1100}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001101
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001102static void
1103fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1104{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001105 PyObject *fval,*ival;
1106#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001107 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001108#else
1109 ival = PyInt_FromLong((long)sec);
1110#endif
1111 if (_stat_float_times) {
1112 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1113 } else {
1114 fval = ival;
1115 Py_INCREF(fval);
1116 }
1117 PyStructSequence_SET_ITEM(v, index, ival);
1118 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001119}
1120
Tim Peters5aa91602002-01-30 05:46:57 +00001121/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001122 (used by posix_stat() and posix_fstat()) */
1123static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001124_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001125{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001126 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001127 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001128 if (v == NULL)
1129 return NULL;
1130
Martin v. Löwis14694662006-02-03 12:54:16 +00001131 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001132#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001133 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001134 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001135#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001136 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001137#endif
1138#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001139 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001140 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001141#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001142 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001143#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001144 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1145 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1146 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001147#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001148 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001149 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001150#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001151 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001152#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001153
Martin v. Löwis14694662006-02-03 12:54:16 +00001154#if defined(HAVE_STAT_TV_NSEC)
1155 ansec = st->st_atim.tv_nsec;
1156 mnsec = st->st_mtim.tv_nsec;
1157 cnsec = st->st_ctim.tv_nsec;
1158#elif defined(HAVE_STAT_TV_NSEC2)
1159 ansec = st->st_atimespec.tv_nsec;
1160 mnsec = st->st_mtimespec.tv_nsec;
1161 cnsec = st->st_ctimespec.tv_nsec;
1162#elif defined(HAVE_STAT_NSEC)
1163 ansec = st->st_atime_nsec;
1164 mnsec = st->st_mtime_nsec;
1165 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001166#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001167 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001168#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001169 fill_time(v, 7, st->st_atime, ansec);
1170 fill_time(v, 8, st->st_mtime, mnsec);
1171 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001172
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001173#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001174 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001175 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001176#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001177#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001178 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001179 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001180#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001181#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001183 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001184#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001185#ifdef HAVE_STRUCT_STAT_ST_GEN
1186 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001187 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001188#endif
1189#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1190 {
1191 PyObject *val;
1192 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001193 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001194#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001195 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001196#else
1197 bnsec = 0;
1198#endif
1199 if (_stat_float_times) {
1200 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1201 } else {
1202 val = PyInt_FromLong((long)bsec);
1203 }
1204 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1205 val);
1206 }
1207#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001208#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1209 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001210 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001211#endif
Fred Drake699f3522000-06-29 21:12:41 +00001212
1213 if (PyErr_Occurred()) {
1214 Py_DECREF(v);
1215 return NULL;
1216 }
1217
1218 return v;
1219}
1220
Martin v. Löwisd8948722004-06-02 09:57:56 +00001221#ifdef MS_WINDOWS
1222
1223/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1224 where / can be used in place of \ and the trailing slash is optional.
1225 Both SERVER and SHARE must have at least one character.
1226*/
1227
1228#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1229#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001230#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001231#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001232#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001233
Tim Peters4ad82172004-08-30 17:02:04 +00001234static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001235IsUNCRootA(char *path, int pathlen)
1236{
1237 #define ISSLASH ISSLASHA
1238
1239 int i, share;
1240
1241 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1242 /* minimum UNCRoot is \\x\y */
1243 return FALSE;
1244 for (i = 2; i < pathlen ; i++)
1245 if (ISSLASH(path[i])) break;
1246 if (i == 2 || i == pathlen)
1247 /* do not allow \\\SHARE or \\SERVER */
1248 return FALSE;
1249 share = i+1;
1250 for (i = share; i < pathlen; i++)
1251 if (ISSLASH(path[i])) break;
1252 return (i != share && (i == pathlen || i == pathlen-1));
1253
1254 #undef ISSLASH
1255}
1256
1257#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001258static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001259IsUNCRootW(Py_UNICODE *path, int pathlen)
1260{
1261 #define ISSLASH ISSLASHW
1262
1263 int i, share;
1264
1265 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1266 /* minimum UNCRoot is \\x\y */
1267 return FALSE;
1268 for (i = 2; i < pathlen ; i++)
1269 if (ISSLASH(path[i])) break;
1270 if (i == 2 || i == pathlen)
1271 /* do not allow \\\SHARE or \\SERVER */
1272 return FALSE;
1273 share = i+1;
1274 for (i = share; i < pathlen; i++)
1275 if (ISSLASH(path[i])) break;
1276 return (i != share && (i == pathlen || i == pathlen-1));
1277
1278 #undef ISSLASH
1279}
1280#endif /* Py_WIN_WIDE_FILENAMES */
1281#endif /* MS_WINDOWS */
1282
Barry Warsaw53699e91996-12-10 23:23:01 +00001283static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001284posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001285 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001286#ifdef __VMS
1287 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1288#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001289 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001290#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001291 char *wformat,
1292 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293{
Fred Drake699f3522000-06-29 21:12:41 +00001294 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001295 char *path = NULL; /* pass this to stat; do not free() it */
1296 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001297 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001298 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001299
1300#ifdef Py_WIN_WIDE_FILENAMES
1301 /* If on wide-character-capable OS see if argument
1302 is Unicode and if so use wide API. */
1303 if (unicode_file_names()) {
1304 PyUnicodeObject *po;
1305 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001306 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1307
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001308 Py_BEGIN_ALLOW_THREADS
1309 /* PyUnicode_AS_UNICODE result OK without
1310 thread lock as it is a simple dereference. */
1311 res = wstatfunc(wpath, &st);
1312 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001313
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001314 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001315 return win32_error_unicode("stat", wpath);
1316 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001317 }
1318 /* Drop the argument parsing error as narrow strings
1319 are also valid. */
1320 PyErr_Clear();
1321 }
1322#endif
1323
Tim Peters5aa91602002-01-30 05:46:57 +00001324 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001325 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001327 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001328
Barry Warsaw53699e91996-12-10 23:23:01 +00001329 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001330 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001331 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001332
1333 if (res != 0) {
1334#ifdef MS_WINDOWS
1335 result = win32_error("stat", pathfree);
1336#else
1337 result = posix_error_with_filename(pathfree);
1338#endif
1339 }
1340 else
1341 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001342
Tim Peters500bd032001-12-19 19:05:01 +00001343 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001344 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345}
1346
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347/* POSIX methods */
1348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001349PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001350"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001351Use the real uid/gid to test for access to a path. Note that most\n\
1352operations will use the effective uid/gid, therefore this routine can\n\
1353be used in a suid/sgid environment to test if the invoking user has the\n\
1354specified access to the path. The mode argument can be F_OK to test\n\
1355existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001356
1357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001358posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001359{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001360 char *path;
1361 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001362
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001363#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001364 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001365 if (unicode_file_names()) {
1366 PyUnicodeObject *po;
1367 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1368 Py_BEGIN_ALLOW_THREADS
1369 /* PyUnicode_AS_UNICODE OK without thread lock as
1370 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001371 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001372 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001373 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001374 }
1375 /* Drop the argument parsing error as narrow strings
1376 are also valid. */
1377 PyErr_Clear();
1378 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001379 if (!PyArg_ParseTuple(args, "eti:access",
1380 Py_FileSystemDefaultEncoding, &path, &mode))
1381 return 0;
1382 Py_BEGIN_ALLOW_THREADS
1383 attr = GetFileAttributesA(path);
1384 Py_END_ALLOW_THREADS
1385 PyMem_Free(path);
1386finish:
1387 if (attr == 0xFFFFFFFF)
1388 /* File does not exist, or cannot read attributes */
1389 return PyBool_FromLong(0);
1390 /* Access is possible if either write access wasn't requested, or
1391 the file isn't read-only. */
1392 return PyBool_FromLong(!(mode & 2) || !(attr && FILE_ATTRIBUTE_READONLY));
1393#else
1394 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001395 if (!PyArg_ParseTuple(args, "eti:access",
1396 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001397 return NULL;
1398 Py_BEGIN_ALLOW_THREADS
1399 res = access(path, mode);
1400 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001401 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001402 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001403#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001404}
1405
Guido van Rossumd371ff11999-01-25 16:12:23 +00001406#ifndef F_OK
1407#define F_OK 0
1408#endif
1409#ifndef R_OK
1410#define R_OK 4
1411#endif
1412#ifndef W_OK
1413#define W_OK 2
1414#endif
1415#ifndef X_OK
1416#define X_OK 1
1417#endif
1418
1419#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001421"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001422Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001423
1424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001425posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001426{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001427 int id;
1428 char *ret;
1429
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001430 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001431 return NULL;
1432
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001433#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001434 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001435 if (id == 0) {
1436 ret = ttyname();
1437 }
1438 else {
1439 ret = NULL;
1440 }
1441#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001442 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001443#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001444 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001445 return posix_error();
1446 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001447}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001448#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001449
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001450#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001451PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001452"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001453Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001454
1455static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001456posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001457{
1458 char *ret;
1459 char buffer[L_ctermid];
1460
Greg Wardb48bc172000-03-01 21:51:56 +00001461#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001462 ret = ctermid_r(buffer);
1463#else
1464 ret = ctermid(buffer);
1465#endif
1466 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001467 return posix_error();
1468 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001469}
1470#endif
1471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001472PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001473"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001474Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001475
Barry Warsaw53699e91996-12-10 23:23:01 +00001476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001477posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001478{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001480 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001481#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001482 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001483#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001484 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001485#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001486 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001487#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001488}
1489
Fred Drake4d1e64b2002-04-15 19:40:07 +00001490#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001491PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001492"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001493Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001494opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001495
1496static PyObject *
1497posix_fchdir(PyObject *self, PyObject *fdobj)
1498{
1499 return posix_fildes(fdobj, fchdir);
1500}
1501#endif /* HAVE_FCHDIR */
1502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001503
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001504PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001505"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001507
Barry Warsaw53699e91996-12-10 23:23:01 +00001508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001509posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001510{
Mark Hammondef8b6542001-05-13 08:04:26 +00001511 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001512 int i;
1513 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001514#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001515 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001516 if (unicode_file_names()) {
1517 PyUnicodeObject *po;
1518 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1519 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001520 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1521 if (attr != 0xFFFFFFFF) {
1522 if (i & _S_IWRITE)
1523 attr &= ~FILE_ATTRIBUTE_READONLY;
1524 else
1525 attr |= FILE_ATTRIBUTE_READONLY;
1526 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1527 }
1528 else
1529 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001530 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001531 if (!res)
1532 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001533 PyUnicode_AS_UNICODE(po));
1534 Py_INCREF(Py_None);
1535 return Py_None;
1536 }
1537 /* Drop the argument parsing error as narrow strings
1538 are also valid. */
1539 PyErr_Clear();
1540 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001541 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1542 &path, &i))
1543 return NULL;
1544 Py_BEGIN_ALLOW_THREADS
1545 attr = GetFileAttributesA(path);
1546 if (attr != 0xFFFFFFFF) {
1547 if (i & _S_IWRITE)
1548 attr &= ~FILE_ATTRIBUTE_READONLY;
1549 else
1550 attr |= FILE_ATTRIBUTE_READONLY;
1551 res = SetFileAttributesA(path, attr);
1552 }
1553 else
1554 res = 0;
1555 Py_END_ALLOW_THREADS
1556 if (!res) {
1557 win32_error("chmod", path);
1558 PyMem_Free(path);
1559 return NULL;
1560 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001561 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001562 Py_INCREF(Py_None);
1563 return Py_None;
1564#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001565 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001566 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001567 return NULL;
1568 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001569 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001570 Py_END_ALLOW_THREADS
1571 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001572 return posix_error_with_allocated_filename(path);
1573 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001574 Py_INCREF(Py_None);
1575 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001576#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001577}
1578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001579
Martin v. Löwis244edc82001-10-04 22:44:26 +00001580#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001581PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001582"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001583Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001584
1585static PyObject *
1586posix_chroot(PyObject *self, PyObject *args)
1587{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001588 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001589}
1590#endif
1591
Guido van Rossum21142a01999-01-08 21:05:37 +00001592#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001593PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001594"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001595force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001596
1597static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001598posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001599{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001600 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001601}
1602#endif /* HAVE_FSYNC */
1603
1604#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001605
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001606#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001607extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1608#endif
1609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001611"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001612force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001614
1615static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001616posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001617{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001618 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001619}
1620#endif /* HAVE_FDATASYNC */
1621
1622
Fredrik Lundh10723342000-07-10 16:38:09 +00001623#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001624PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001625"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001626Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001627
Barry Warsaw53699e91996-12-10 23:23:01 +00001628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001629posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001630{
Mark Hammondef8b6542001-05-13 08:04:26 +00001631 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001632 int uid, gid;
1633 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001634 if (!PyArg_ParseTuple(args, "etii:chown",
1635 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001636 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001637 return NULL;
1638 Py_BEGIN_ALLOW_THREADS
1639 res = chown(path, (uid_t) uid, (gid_t) gid);
1640 Py_END_ALLOW_THREADS
1641 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001642 return posix_error_with_allocated_filename(path);
1643 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001644 Py_INCREF(Py_None);
1645 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001646}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001647#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001648
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001649#ifdef HAVE_LCHOWN
1650PyDoc_STRVAR(posix_lchown__doc__,
1651"lchown(path, uid, gid)\n\n\
1652Change the owner and group id of path to the numeric uid and gid.\n\
1653This function will not follow symbolic links.");
1654
1655static PyObject *
1656posix_lchown(PyObject *self, PyObject *args)
1657{
1658 char *path = NULL;
1659 int uid, gid;
1660 int res;
1661 if (!PyArg_ParseTuple(args, "etii:lchown",
1662 Py_FileSystemDefaultEncoding, &path,
1663 &uid, &gid))
1664 return NULL;
1665 Py_BEGIN_ALLOW_THREADS
1666 res = lchown(path, (uid_t) uid, (gid_t) gid);
1667 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001668 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001669 return posix_error_with_allocated_filename(path);
1670 PyMem_Free(path);
1671 Py_INCREF(Py_None);
1672 return Py_None;
1673}
1674#endif /* HAVE_LCHOWN */
1675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001676
Guido van Rossum36bc6801995-06-14 22:54:23 +00001677#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001678PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001679"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001680Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001681
Barry Warsaw53699e91996-12-10 23:23:01 +00001682static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001683posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001684{
1685 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001686 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001687
Barry Warsaw53699e91996-12-10 23:23:01 +00001688 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001689#if defined(PYOS_OS2) && defined(PYCC_GCC)
1690 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001691#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001692 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001693#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001694 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001695 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001696 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001697 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001698}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001699
Walter Dörwald3b918c32002-11-21 20:18:46 +00001700#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001701PyDoc_STRVAR(posix_getcwdu__doc__,
1702"getcwdu() -> path\n\n\
1703Return a unicode string representing the current working directory.");
1704
1705static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001706posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001707{
1708 char buf[1026];
1709 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001710
1711#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001712 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001713 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001714 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001715 wchar_t *wbuf2 = wbuf;
1716 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001717 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001718 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1719 /* If the buffer is large enough, len does not include the
1720 terminating \0. If the buffer is too small, len includes
1721 the space needed for the terminator. */
1722 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1723 wbuf2 = malloc(len * sizeof(wchar_t));
1724 if (wbuf2)
1725 len = GetCurrentDirectoryW(len, wbuf2);
1726 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001728 if (!wbuf2) {
1729 PyErr_NoMemory();
1730 return NULL;
1731 }
1732 if (!len) {
1733 if (wbuf2 != wbuf) free(wbuf2);
1734 return win32_error("getcwdu", NULL);
1735 }
1736 resobj = PyUnicode_FromWideChar(wbuf2, len);
1737 if (wbuf2 != wbuf) free(wbuf2);
1738 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001739 }
1740#endif
1741
1742 Py_BEGIN_ALLOW_THREADS
1743#if defined(PYOS_OS2) && defined(PYCC_GCC)
1744 res = _getcwd2(buf, sizeof buf);
1745#else
1746 res = getcwd(buf, sizeof buf);
1747#endif
1748 Py_END_ALLOW_THREADS
1749 if (res == NULL)
1750 return posix_error();
1751 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1752}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001753#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001754#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001756
Guido van Rossumb6775db1994-08-01 11:34:53 +00001757#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001758PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001759"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001760Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001761
Barry Warsaw53699e91996-12-10 23:23:01 +00001762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001763posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001764{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00001765 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001766}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001767#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001768
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001770PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001771"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001772Return a list containing the names of the entries in the directory.\n\
1773\n\
1774 path: path of directory to list\n\
1775\n\
1776The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001777entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001778
Barry Warsaw53699e91996-12-10 23:23:01 +00001779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001780posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001781{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001782 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001783 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001784#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001785
Barry Warsaw53699e91996-12-10 23:23:01 +00001786 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001787 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001788 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001789 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001790 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001791 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001792 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001793
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001794#ifdef Py_WIN_WIDE_FILENAMES
1795 /* If on wide-character-capable OS see if argument
1796 is Unicode and if so use wide API. */
1797 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001798 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001799 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1800 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001801 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001802 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001803 /* Overallocate for \\*.*\0 */
1804 len = PyUnicode_GET_SIZE(po);
1805 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1806 if (!wnamebuf) {
1807 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001808 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001809 }
1810 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1811 wch = len > 0 ? wnamebuf[len-1] : '\0';
1812 if (wch != L'/' && wch != L'\\' && wch != L':')
1813 wnamebuf[len++] = L'\\';
1814 wcscpy(wnamebuf + len, L"*.*");
1815 if ((d = PyList_New(0)) == NULL) {
1816 free(wnamebuf);
1817 return NULL;
1818 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001819 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1820 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001821 int error = GetLastError();
1822 if (error == ERROR_FILE_NOT_FOUND) {
1823 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001824 return d;
1825 }
1826 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001827 win32_error_unicode("FindFirstFileW", wnamebuf);
1828 free(wnamebuf);
1829 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001830 }
1831 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001832 /* Skip over . and .. */
1833 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1834 wcscmp(wFileData.cFileName, L"..") != 0) {
1835 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1836 if (v == NULL) {
1837 Py_DECREF(d);
1838 d = NULL;
1839 break;
1840 }
1841 if (PyList_Append(d, v) != 0) {
1842 Py_DECREF(v);
1843 Py_DECREF(d);
1844 d = NULL;
1845 break;
1846 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001847 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001848 }
Georg Brandl622927b2006-03-07 12:48:03 +00001849 Py_BEGIN_ALLOW_THREADS
1850 result = FindNextFileW(hFindFile, &wFileData);
1851 Py_END_ALLOW_THREADS
1852 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001853
1854 if (FindClose(hFindFile) == FALSE) {
1855 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001856 win32_error_unicode("FindClose", wnamebuf);
1857 free(wnamebuf);
1858 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001859 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00001860 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001861 return d;
1862 }
1863 /* Drop the argument parsing error as narrow strings
1864 are also valid. */
1865 PyErr_Clear();
1866 }
1867#endif
1868
Tim Peters5aa91602002-01-30 05:46:57 +00001869 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001870 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001871 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001872 if (len > 0) {
1873 char ch = namebuf[len-1];
1874 if (ch != SEP && ch != ALTSEP && ch != ':')
1875 namebuf[len++] = '/';
1876 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001877 strcpy(namebuf + len, "*.*");
1878
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001880 return NULL;
1881
1882 hFindFile = FindFirstFile(namebuf, &FileData);
1883 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001884 int error = GetLastError();
1885 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001886 return d;
1887 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001888 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001889 }
1890 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001891 /* Skip over . and .. */
1892 if (strcmp(FileData.cFileName, ".") != 0 &&
1893 strcmp(FileData.cFileName, "..") != 0) {
1894 v = PyString_FromString(FileData.cFileName);
1895 if (v == NULL) {
1896 Py_DECREF(d);
1897 d = NULL;
1898 break;
1899 }
1900 if (PyList_Append(d, v) != 0) {
1901 Py_DECREF(v);
1902 Py_DECREF(d);
1903 d = NULL;
1904 break;
1905 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001906 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001907 }
Georg Brandl622927b2006-03-07 12:48:03 +00001908 Py_BEGIN_ALLOW_THREADS
1909 result = FindNextFile(hFindFile, &FileData);
1910 Py_END_ALLOW_THREADS
1911 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001912
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001913 if (FindClose(hFindFile) == FALSE) {
1914 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001915 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001916 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001917
1918 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001919
Tim Peters0bb44a42000-09-15 07:44:49 +00001920#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001921
1922#ifndef MAX_PATH
1923#define MAX_PATH CCHMAXPATH
1924#endif
1925 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001926 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001927 PyObject *d, *v;
1928 char namebuf[MAX_PATH+5];
1929 HDIR hdir = 1;
1930 ULONG srchcnt = 1;
1931 FILEFINDBUF3 ep;
1932 APIRET rc;
1933
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001934 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001935 return NULL;
1936 if (len >= MAX_PATH) {
1937 PyErr_SetString(PyExc_ValueError, "path too long");
1938 return NULL;
1939 }
1940 strcpy(namebuf, name);
1941 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001942 if (*pt == ALTSEP)
1943 *pt = SEP;
1944 if (namebuf[len-1] != SEP)
1945 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001946 strcpy(namebuf + len, "*.*");
1947
1948 if ((d = PyList_New(0)) == NULL)
1949 return NULL;
1950
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001951 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1952 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001953 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001954 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1955 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1956 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001957
1958 if (rc != NO_ERROR) {
1959 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001960 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001961 }
1962
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001963 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001964 do {
1965 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001966 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001967 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001968
1969 strcpy(namebuf, ep.achName);
1970
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001971 /* Leave Case of Name Alone -- In Native Form */
1972 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001973
1974 v = PyString_FromString(namebuf);
1975 if (v == NULL) {
1976 Py_DECREF(d);
1977 d = NULL;
1978 break;
1979 }
1980 if (PyList_Append(d, v) != 0) {
1981 Py_DECREF(v);
1982 Py_DECREF(d);
1983 d = NULL;
1984 break;
1985 }
1986 Py_DECREF(v);
1987 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1988 }
1989
1990 return d;
1991#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001992
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001993 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001994 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001995 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001996 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001997 int arg_is_unicode = 1;
1998
Georg Brandl05e89b82006-04-11 07:04:06 +00001999 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002000 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2001 arg_is_unicode = 0;
2002 PyErr_Clear();
2003 }
2004 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002005 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002006 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002007 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002008 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002009 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002010 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002011 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002012 return NULL;
2013 }
Georg Brandl622927b2006-03-07 12:48:03 +00002014 for (;;) {
2015 Py_BEGIN_ALLOW_THREADS
2016 ep = readdir(dirp);
2017 Py_END_ALLOW_THREADS
2018 if (ep == NULL)
2019 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002020 if (ep->d_name[0] == '.' &&
2021 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002022 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002023 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002025 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002026 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002027 d = NULL;
2028 break;
2029 }
Just van Rossum46c97842003-02-25 21:42:15 +00002030#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002031 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002032 PyObject *w;
2033
2034 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002035 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002036 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002037 if (w != NULL) {
2038 Py_DECREF(v);
2039 v = w;
2040 }
2041 else {
2042 /* fall back to the original byte string, as
2043 discussed in patch #683592 */
2044 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002045 }
Just van Rossum46c97842003-02-25 21:42:15 +00002046 }
2047#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002048 if (PyList_Append(d, v) != 0) {
2049 Py_DECREF(v);
2050 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002051 d = NULL;
2052 break;
2053 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002054 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00002056 if (errno != 0 && d != NULL) {
2057 /* readdir() returned NULL and set errno */
2058 closedir(dirp);
2059 Py_DECREF(d);
2060 return posix_error_with_allocated_filename(name);
2061 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002063 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002064
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002065 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002066
Tim Peters0bb44a42000-09-15 07:44:49 +00002067#endif /* which OS */
2068} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002069
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002070#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002071/* A helper function for abspath on win32 */
2072static PyObject *
2073posix__getfullpathname(PyObject *self, PyObject *args)
2074{
2075 /* assume encoded strings wont more than double no of chars */
2076 char inbuf[MAX_PATH*2];
2077 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002078 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002079 char outbuf[MAX_PATH*2];
2080 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002081#ifdef Py_WIN_WIDE_FILENAMES
2082 if (unicode_file_names()) {
2083 PyUnicodeObject *po;
2084 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2085 Py_UNICODE woutbuf[MAX_PATH*2];
2086 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002087 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002088 sizeof(woutbuf)/sizeof(woutbuf[0]),
2089 woutbuf, &wtemp))
2090 return win32_error("GetFullPathName", "");
2091 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2092 }
2093 /* Drop the argument parsing error as narrow strings
2094 are also valid. */
2095 PyErr_Clear();
2096 }
2097#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002098 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2099 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002100 &insize))
2101 return NULL;
2102 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2103 outbuf, &temp))
2104 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002105 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2106 return PyUnicode_Decode(outbuf, strlen(outbuf),
2107 Py_FileSystemDefaultEncoding, NULL);
2108 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002109 return PyString_FromString(outbuf);
2110} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002111#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002114"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002116
Barry Warsaw53699e91996-12-10 23:23:01 +00002117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002118posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002119{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002120 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002121 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002122 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002123
2124#ifdef Py_WIN_WIDE_FILENAMES
2125 if (unicode_file_names()) {
2126 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002127 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002128 Py_BEGIN_ALLOW_THREADS
2129 /* PyUnicode_AS_UNICODE OK without thread lock as
2130 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002131 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002132 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002133 if (!res)
2134 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002135 Py_INCREF(Py_None);
2136 return Py_None;
2137 }
2138 /* Drop the argument parsing error as narrow strings
2139 are also valid. */
2140 PyErr_Clear();
2141 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002142 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2143 Py_FileSystemDefaultEncoding, &path, &mode))
2144 return NULL;
2145 Py_BEGIN_ALLOW_THREADS
2146 /* PyUnicode_AS_UNICODE OK without thread lock as
2147 it is a simple dereference. */
2148 res = CreateDirectoryA(path, NULL);
2149 Py_END_ALLOW_THREADS
2150 if (!res) {
2151 win32_error("mkdir", path);
2152 PyMem_Free(path);
2153 return NULL;
2154 }
2155 PyMem_Free(path);
2156 Py_INCREF(Py_None);
2157 return Py_None;
2158#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002159
Tim Peters5aa91602002-01-30 05:46:57 +00002160 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002161 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002162 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002163 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002164#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002165 res = mkdir(path);
2166#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002167 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002168#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002169 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002170 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002171 return posix_error_with_allocated_filename(path);
2172 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002173 Py_INCREF(Py_None);
2174 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002175#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002176}
2177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002178
Neal Norwitz1818ed72006-03-26 00:29:48 +00002179/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2180#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002181#include <sys/resource.h>
2182#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002183
Neal Norwitz1818ed72006-03-26 00:29:48 +00002184
2185#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002186PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002187"nice(inc) -> new_priority\n\n\
2188Decrease the priority of process by inc and return the new priority.");
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_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002192{
2193 int increment, value;
2194
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002195 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002196 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002197
2198 /* There are two flavours of 'nice': one that returns the new
2199 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002200 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2201 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002202
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002203 If we are of the nice family that returns the new priority, we
2204 need to clear errno before the call, and check if errno is filled
2205 before calling posix_error() on a returnvalue of -1, because the
2206 -1 may be the actual new priority! */
2207
2208 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002209 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002210#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002211 if (value == 0)
2212 value = getpriority(PRIO_PROCESS, 0);
2213#endif
2214 if (value == -1 && errno != 0)
2215 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002216 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002217 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002218}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002219#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002221PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002222"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002223Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002224
Barry Warsaw53699e91996-12-10 23:23:01 +00002225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002226posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002227{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002228#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002229 PyObject *o1, *o2;
2230 char *p1, *p2;
2231 BOOL result;
2232 if (unicode_file_names()) {
2233 if (!PyArg_ParseTuple(args, "O&O&:rename",
2234 convert_to_unicode, &o1,
2235 convert_to_unicode, &o2))
2236 PyErr_Clear();
2237 else {
2238 Py_BEGIN_ALLOW_THREADS
2239 result = MoveFileW(PyUnicode_AsUnicode(o1),
2240 PyUnicode_AsUnicode(o2));
2241 Py_END_ALLOW_THREADS
2242 Py_DECREF(o1);
2243 Py_DECREF(o2);
2244 if (!result)
2245 return win32_error("rename", NULL);
2246 Py_INCREF(Py_None);
2247 return Py_None;
2248 }
2249 }
2250 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2251 return NULL;
2252 Py_BEGIN_ALLOW_THREADS
2253 result = MoveFileA(p1, p2);
2254 Py_END_ALLOW_THREADS
2255 if (!result)
2256 return win32_error("rename", NULL);
2257 Py_INCREF(Py_None);
2258 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002259#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002260 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002261#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002262}
2263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002265PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002266"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002267Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002268
Barry Warsaw53699e91996-12-10 23:23:01 +00002269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002270posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002271{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002272#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002273 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002274#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002275 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002276#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002277}
2278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002280PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002281"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002282Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002283
Barry Warsaw53699e91996-12-10 23:23:01 +00002284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002285posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002286{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002287#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002288 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002289#else
2290 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2291#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002292}
2293
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002294
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002295#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002296PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002297"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002299
Barry Warsaw53699e91996-12-10 23:23:01 +00002300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002301posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002302{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002303 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002304 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002305 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002306 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002307 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002308 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002309 Py_END_ALLOW_THREADS
2310 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002311}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002312#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002314
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002315PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002316"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002317Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002318
Barry Warsaw53699e91996-12-10 23:23:01 +00002319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002320posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002321{
2322 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002323 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002324 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002325 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002326 if (i < 0)
2327 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002328 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002329}
2330
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002332PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002333"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002334Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002335
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002336PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002337"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002338Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002339
Barry Warsaw53699e91996-12-10 23:23:01 +00002340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002341posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002343#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002344 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002345#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002346 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002347#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002348}
2349
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002350
Guido van Rossumb6775db1994-08-01 11:34:53 +00002351#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002352PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002353"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002354Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002355
Barry Warsaw53699e91996-12-10 23:23:01 +00002356static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002357posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002358{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002359 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002360 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002361
Barry Warsaw53699e91996-12-10 23:23:01 +00002362 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002363 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002364 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002365 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002366 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002367 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002368 u.sysname,
2369 u.nodename,
2370 u.release,
2371 u.version,
2372 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002373}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002374#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002375
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002376static int
2377extract_time(PyObject *t, long* sec, long* usec)
2378{
2379 long intval;
2380 if (PyFloat_Check(t)) {
2381 double tval = PyFloat_AsDouble(t);
2382 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2383 if (!intobj)
2384 return -1;
2385 intval = PyInt_AsLong(intobj);
2386 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002387 if (intval == -1 && PyErr_Occurred())
2388 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002389 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002390 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002391 if (*usec < 0)
2392 /* If rounding gave us a negative number,
2393 truncate. */
2394 *usec = 0;
2395 return 0;
2396 }
2397 intval = PyInt_AsLong(t);
2398 if (intval == -1 && PyErr_Occurred())
2399 return -1;
2400 *sec = intval;
2401 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002402 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002403}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002405PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002406"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002407utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002408Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002409second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002410
Barry Warsaw53699e91996-12-10 23:23:01 +00002411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002412posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002413{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002414#ifdef Py_WIN_WIDE_FILENAMES
2415 PyObject *arg;
2416 PyUnicodeObject *obwpath;
2417 wchar_t *wpath = NULL;
2418 char *apath = NULL;
2419 HANDLE hFile;
2420 long atimesec, mtimesec, ausec, musec;
2421 FILETIME atime, mtime;
2422 PyObject *result = NULL;
2423
2424 if (unicode_file_names()) {
2425 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2426 wpath = PyUnicode_AS_UNICODE(obwpath);
2427 Py_BEGIN_ALLOW_THREADS
2428 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2429 NULL, OPEN_EXISTING, 0, NULL);
2430 Py_END_ALLOW_THREADS
2431 if (hFile == INVALID_HANDLE_VALUE)
2432 return win32_error_unicode("utime", wpath);
2433 } else
2434 /* Drop the argument parsing error as narrow strings
2435 are also valid. */
2436 PyErr_Clear();
2437 }
2438 if (!wpath) {
2439 if (!PyArg_ParseTuple(args, "etO:utime",
2440 Py_FileSystemDefaultEncoding, &apath, &arg))
2441 return NULL;
2442 Py_BEGIN_ALLOW_THREADS
2443 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2444 NULL, OPEN_EXISTING, 0, NULL);
2445 Py_END_ALLOW_THREADS
2446 if (hFile == INVALID_HANDLE_VALUE) {
2447 win32_error("utime", apath);
2448 PyMem_Free(apath);
2449 return NULL;
2450 }
2451 PyMem_Free(apath);
2452 }
2453
2454 if (arg == Py_None) {
2455 SYSTEMTIME now;
2456 GetSystemTime(&now);
2457 if (!SystemTimeToFileTime(&now, &mtime) ||
2458 !SystemTimeToFileTime(&now, &atime)) {
2459 win32_error("utime", NULL);
2460 goto done;
2461 }
2462 }
2463 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2464 PyErr_SetString(PyExc_TypeError,
2465 "utime() arg 2 must be a tuple (atime, mtime)");
2466 goto done;
2467 }
2468 else {
2469 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2470 &atimesec, &ausec) == -1)
2471 goto done;
2472 time_t_to_FILE_TIME(atimesec, ausec, &atime);
2473 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2474 &mtimesec, &musec) == -1)
2475 goto done;
2476 time_t_to_FILE_TIME(mtimesec, musec, &mtime);
2477 }
2478 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2479 /* Avoid putting the file name into the error here,
2480 as that may confuse the user into believing that
2481 something is wrong with the file, when it also
2482 could be the time stamp that gives a problem. */
2483 win32_error("utime", NULL);
2484 }
2485 Py_INCREF(Py_None);
2486 result = Py_None;
2487done:
2488 CloseHandle(hFile);
2489 return result;
2490#else /* Py_WIN_WIDE_FILENAMES */
2491
Neal Norwitz2adf2102004-06-09 01:46:02 +00002492 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002493 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002494 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002495 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002496
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002497#if defined(HAVE_UTIMES)
2498 struct timeval buf[2];
2499#define ATIME buf[0].tv_sec
2500#define MTIME buf[1].tv_sec
2501#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002502/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002503 struct utimbuf buf;
2504#define ATIME buf.actime
2505#define MTIME buf.modtime
2506#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002507#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002508 time_t buf[2];
2509#define ATIME buf[0]
2510#define MTIME buf[1]
2511#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002512#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002513
Mark Hammond817c9292003-12-03 01:22:38 +00002514
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002515 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002516 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002517 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002518 if (arg == Py_None) {
2519 /* optional time values not given */
2520 Py_BEGIN_ALLOW_THREADS
2521 res = utime(path, NULL);
2522 Py_END_ALLOW_THREADS
2523 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002524 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002525 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002526 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002527 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002528 return NULL;
2529 }
2530 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002531 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002532 &atime, &ausec) == -1) {
2533 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002534 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002535 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002536 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002537 &mtime, &musec) == -1) {
2538 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002539 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002540 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002541 ATIME = atime;
2542 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002543#ifdef HAVE_UTIMES
2544 buf[0].tv_usec = ausec;
2545 buf[1].tv_usec = musec;
2546 Py_BEGIN_ALLOW_THREADS
2547 res = utimes(path, buf);
2548 Py_END_ALLOW_THREADS
2549#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002550 Py_BEGIN_ALLOW_THREADS
2551 res = utime(path, UTIME_ARG);
2552 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002553#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002554 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002555 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002556 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002557 }
Neal Norwitz96652712004-06-06 20:40:27 +00002558 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002559 Py_INCREF(Py_None);
2560 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002561#undef UTIME_ARG
2562#undef ATIME
2563#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002564#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002565}
2566
Guido van Rossum85e3b011991-06-03 12:42:10 +00002567
Guido van Rossum3b066191991-06-04 19:40:25 +00002568/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002570PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002571"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002572Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002573
Barry Warsaw53699e91996-12-10 23:23:01 +00002574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002575posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002576{
2577 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002578 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002579 return NULL;
2580 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002581 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002582}
2583
Martin v. Löwis114619e2002-10-07 06:44:21 +00002584#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2585static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002586free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002587{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002588 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002589 for (i = 0; i < count; i++)
2590 PyMem_Free(array[i]);
2591 PyMem_DEL(array);
2592}
2593#endif
2594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002595
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002596#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002597PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002598"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002599Execute an executable path with arguments, replacing current process.\n\
2600\n\
2601 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002602 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002603
Barry Warsaw53699e91996-12-10 23:23:01 +00002604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002605posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002606{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002607 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002608 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002609 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002610 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002611 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002612
Guido van Rossum89b33251993-10-22 14:26:06 +00002613 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002614 argv is a list or tuple of strings. */
2615
Martin v. Löwis114619e2002-10-07 06:44:21 +00002616 if (!PyArg_ParseTuple(args, "etO:execv",
2617 Py_FileSystemDefaultEncoding,
2618 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002619 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002620 if (PyList_Check(argv)) {
2621 argc = PyList_Size(argv);
2622 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002623 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002624 else if (PyTuple_Check(argv)) {
2625 argc = PyTuple_Size(argv);
2626 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002627 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002628 else {
Fred Drake661ea262000-10-24 19:57:45 +00002629 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002630 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002631 return NULL;
2632 }
2633
Barry Warsaw53699e91996-12-10 23:23:01 +00002634 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002635 if (argvlist == NULL) {
2636 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002637 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002638 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002639 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002640 if (!PyArg_Parse((*getitem)(argv, i), "et",
2641 Py_FileSystemDefaultEncoding,
2642 &argvlist[i])) {
2643 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002644 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002645 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002646 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002647 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002648
Guido van Rossum85e3b011991-06-03 12:42:10 +00002649 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002650 }
2651 argvlist[argc] = NULL;
2652
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002653 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002654
Guido van Rossum85e3b011991-06-03 12:42:10 +00002655 /* If we get here it's definitely an error */
2656
Martin v. Löwis114619e2002-10-07 06:44:21 +00002657 free_string_array(argvlist, argc);
2658 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002659 return posix_error();
2660}
2661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002664"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002665Execute a path with arguments and environment, replacing current process.\n\
2666\n\
2667 path: path of executable file\n\
2668 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Barry Warsaw53699e91996-12-10 23:23:01 +00002671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002672posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002673{
2674 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002675 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002676 char **argvlist;
2677 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002678 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002679 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002680 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002681 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002682
2683 /* execve has three arguments: (path, argv, env), where
2684 argv is a list or tuple of strings and env is a dictionary
2685 like posix.environ. */
2686
Martin v. Löwis114619e2002-10-07 06:44:21 +00002687 if (!PyArg_ParseTuple(args, "etOO:execve",
2688 Py_FileSystemDefaultEncoding,
2689 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002690 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002691 if (PyList_Check(argv)) {
2692 argc = PyList_Size(argv);
2693 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002694 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002695 else if (PyTuple_Check(argv)) {
2696 argc = PyTuple_Size(argv);
2697 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002698 }
2699 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002700 PyErr_SetString(PyExc_TypeError,
2701 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002702 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002703 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002704 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002705 PyErr_SetString(PyExc_TypeError,
2706 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002707 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002708 }
2709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002711 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002712 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002713 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002714 }
2715 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002716 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002717 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002718 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002719 &argvlist[i]))
2720 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002721 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002722 goto fail_1;
2723 }
2724 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002725 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002726 argvlist[argc] = NULL;
2727
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002728 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002729 if (i < 0)
2730 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002731 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002732 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002733 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002734 goto fail_1;
2735 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002736 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002737 keys = PyMapping_Keys(env);
2738 vals = PyMapping_Values(env);
2739 if (!keys || !vals)
2740 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002741 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2742 PyErr_SetString(PyExc_TypeError,
2743 "execve(): env.keys() or env.values() is not a list");
2744 goto fail_2;
2745 }
Tim Peters5aa91602002-01-30 05:46:57 +00002746
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002747 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002748 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002749 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002750
2751 key = PyList_GetItem(keys, pos);
2752 val = PyList_GetItem(vals, pos);
2753 if (!key || !val)
2754 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002755
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002756 if (!PyArg_Parse(
2757 key,
2758 "s;execve() arg 3 contains a non-string key",
2759 &k) ||
2760 !PyArg_Parse(
2761 val,
2762 "s;execve() arg 3 contains a non-string value",
2763 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002764 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002765 goto fail_2;
2766 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002767
2768#if defined(PYOS_OS2)
2769 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2770 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2771#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002772 len = PyString_Size(key) + PyString_Size(val) + 2;
2773 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002774 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002775 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002776 goto fail_2;
2777 }
Tim Petersc8996f52001-12-03 20:41:00 +00002778 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002779 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002780#if defined(PYOS_OS2)
2781 }
2782#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002783 }
2784 envlist[envc] = 0;
2785
2786 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002787
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002788 /* If we get here it's definitely an error */
2789
2790 (void) posix_error();
2791
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002792 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002793 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002794 PyMem_DEL(envlist[envc]);
2795 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002796 fail_1:
2797 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002798 Py_XDECREF(vals);
2799 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002800 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002801 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002802 return NULL;
2803}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002804#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002806
Guido van Rossuma1065681999-01-25 23:20:23 +00002807#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002808PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002809"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002810Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002811\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002812 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002813 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002814 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002815
2816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002817posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002818{
2819 char *path;
2820 PyObject *argv;
2821 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002822 int mode, i;
2823 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002824 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002825 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002826
2827 /* spawnv has three arguments: (mode, path, argv), where
2828 argv is a list or tuple of strings. */
2829
Martin v. Löwis114619e2002-10-07 06:44:21 +00002830 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2831 Py_FileSystemDefaultEncoding,
2832 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002833 return NULL;
2834 if (PyList_Check(argv)) {
2835 argc = PyList_Size(argv);
2836 getitem = PyList_GetItem;
2837 }
2838 else if (PyTuple_Check(argv)) {
2839 argc = PyTuple_Size(argv);
2840 getitem = PyTuple_GetItem;
2841 }
2842 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002843 PyErr_SetString(PyExc_TypeError,
2844 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002845 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002846 return NULL;
2847 }
2848
2849 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002850 if (argvlist == NULL) {
2851 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002852 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002853 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002854 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002855 if (!PyArg_Parse((*getitem)(argv, i), "et",
2856 Py_FileSystemDefaultEncoding,
2857 &argvlist[i])) {
2858 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002859 PyErr_SetString(
2860 PyExc_TypeError,
2861 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002862 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002863 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002864 }
2865 }
2866 argvlist[argc] = NULL;
2867
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002868#if defined(PYOS_OS2) && defined(PYCC_GCC)
2869 Py_BEGIN_ALLOW_THREADS
2870 spawnval = spawnv(mode, path, argvlist);
2871 Py_END_ALLOW_THREADS
2872#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002873 if (mode == _OLD_P_OVERLAY)
2874 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002875
Tim Peters25059d32001-12-07 20:35:43 +00002876 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002877 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002878 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002879#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002880
Martin v. Löwis114619e2002-10-07 06:44:21 +00002881 free_string_array(argvlist, argc);
2882 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002883
Fred Drake699f3522000-06-29 21:12:41 +00002884 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002885 return posix_error();
2886 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002887#if SIZEOF_LONG == SIZEOF_VOID_P
2888 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002889#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002890 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002891#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002892}
2893
2894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002896"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002897Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002898\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002899 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002900 path: path of executable file\n\
2901 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002902 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002903
2904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002905posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002906{
2907 char *path;
2908 PyObject *argv, *env;
2909 char **argvlist;
2910 char **envlist;
2911 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002912 int mode, pos, envc;
2913 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002914 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002915 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002916 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002917
2918 /* spawnve has four arguments: (mode, path, argv, env), where
2919 argv is a list or tuple of strings and env is a dictionary
2920 like posix.environ. */
2921
Martin v. Löwis114619e2002-10-07 06:44:21 +00002922 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2923 Py_FileSystemDefaultEncoding,
2924 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002925 return NULL;
2926 if (PyList_Check(argv)) {
2927 argc = PyList_Size(argv);
2928 getitem = PyList_GetItem;
2929 }
2930 else if (PyTuple_Check(argv)) {
2931 argc = PyTuple_Size(argv);
2932 getitem = PyTuple_GetItem;
2933 }
2934 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002935 PyErr_SetString(PyExc_TypeError,
2936 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002937 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002938 }
2939 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002940 PyErr_SetString(PyExc_TypeError,
2941 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002942 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002943 }
2944
2945 argvlist = PyMem_NEW(char *, argc+1);
2946 if (argvlist == NULL) {
2947 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002948 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002949 }
2950 for (i = 0; i < argc; i++) {
2951 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002952 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002953 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002954 &argvlist[i]))
2955 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002957 goto fail_1;
2958 }
2959 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002960 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002961 argvlist[argc] = NULL;
2962
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002963 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002964 if (i < 0)
2965 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002966 envlist = PyMem_NEW(char *, i + 1);
2967 if (envlist == NULL) {
2968 PyErr_NoMemory();
2969 goto fail_1;
2970 }
2971 envc = 0;
2972 keys = PyMapping_Keys(env);
2973 vals = PyMapping_Values(env);
2974 if (!keys || !vals)
2975 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002976 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2977 PyErr_SetString(PyExc_TypeError,
2978 "spawnve(): env.keys() or env.values() is not a list");
2979 goto fail_2;
2980 }
Tim Peters5aa91602002-01-30 05:46:57 +00002981
Guido van Rossuma1065681999-01-25 23:20:23 +00002982 for (pos = 0; pos < i; pos++) {
2983 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002984 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002985
2986 key = PyList_GetItem(keys, pos);
2987 val = PyList_GetItem(vals, pos);
2988 if (!key || !val)
2989 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002990
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002991 if (!PyArg_Parse(
2992 key,
2993 "s;spawnve() arg 3 contains a non-string key",
2994 &k) ||
2995 !PyArg_Parse(
2996 val,
2997 "s;spawnve() arg 3 contains a non-string value",
2998 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002999 {
3000 goto fail_2;
3001 }
Tim Petersc8996f52001-12-03 20:41:00 +00003002 len = PyString_Size(key) + PyString_Size(val) + 2;
3003 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003004 if (p == NULL) {
3005 PyErr_NoMemory();
3006 goto fail_2;
3007 }
Tim Petersc8996f52001-12-03 20:41:00 +00003008 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003009 envlist[envc++] = p;
3010 }
3011 envlist[envc] = 0;
3012
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003013#if defined(PYOS_OS2) && defined(PYCC_GCC)
3014 Py_BEGIN_ALLOW_THREADS
3015 spawnval = spawnve(mode, path, argvlist, envlist);
3016 Py_END_ALLOW_THREADS
3017#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003018 if (mode == _OLD_P_OVERLAY)
3019 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003020
3021 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003022 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003023 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003024#endif
Tim Peters25059d32001-12-07 20:35:43 +00003025
Fred Drake699f3522000-06-29 21:12:41 +00003026 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003027 (void) posix_error();
3028 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003029#if SIZEOF_LONG == SIZEOF_VOID_P
3030 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003031#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003032 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003033#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003034
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003035 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003036 while (--envc >= 0)
3037 PyMem_DEL(envlist[envc]);
3038 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003039 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003040 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003041 Py_XDECREF(vals);
3042 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003043 fail_0:
3044 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003045 return res;
3046}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003047
3048/* OS/2 supports spawnvp & spawnvpe natively */
3049#if defined(PYOS_OS2)
3050PyDoc_STRVAR(posix_spawnvp__doc__,
3051"spawnvp(mode, file, args)\n\n\
3052Execute the program 'file' in a new process, using the environment\n\
3053search path to find the file.\n\
3054\n\
3055 mode: mode of process creation\n\
3056 file: executable file name\n\
3057 args: tuple or list of strings");
3058
3059static PyObject *
3060posix_spawnvp(PyObject *self, PyObject *args)
3061{
3062 char *path;
3063 PyObject *argv;
3064 char **argvlist;
3065 int mode, i, argc;
3066 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003067 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003068
3069 /* spawnvp has three arguments: (mode, path, argv), where
3070 argv is a list or tuple of strings. */
3071
3072 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3073 Py_FileSystemDefaultEncoding,
3074 &path, &argv))
3075 return NULL;
3076 if (PyList_Check(argv)) {
3077 argc = PyList_Size(argv);
3078 getitem = PyList_GetItem;
3079 }
3080 else if (PyTuple_Check(argv)) {
3081 argc = PyTuple_Size(argv);
3082 getitem = PyTuple_GetItem;
3083 }
3084 else {
3085 PyErr_SetString(PyExc_TypeError,
3086 "spawnvp() arg 2 must be a tuple or list");
3087 PyMem_Free(path);
3088 return NULL;
3089 }
3090
3091 argvlist = PyMem_NEW(char *, argc+1);
3092 if (argvlist == NULL) {
3093 PyMem_Free(path);
3094 return PyErr_NoMemory();
3095 }
3096 for (i = 0; i < argc; i++) {
3097 if (!PyArg_Parse((*getitem)(argv, i), "et",
3098 Py_FileSystemDefaultEncoding,
3099 &argvlist[i])) {
3100 free_string_array(argvlist, i);
3101 PyErr_SetString(
3102 PyExc_TypeError,
3103 "spawnvp() arg 2 must contain only strings");
3104 PyMem_Free(path);
3105 return NULL;
3106 }
3107 }
3108 argvlist[argc] = NULL;
3109
3110 Py_BEGIN_ALLOW_THREADS
3111#if defined(PYCC_GCC)
3112 spawnval = spawnvp(mode, path, argvlist);
3113#else
3114 spawnval = _spawnvp(mode, path, argvlist);
3115#endif
3116 Py_END_ALLOW_THREADS
3117
3118 free_string_array(argvlist, argc);
3119 PyMem_Free(path);
3120
3121 if (spawnval == -1)
3122 return posix_error();
3123 else
3124 return Py_BuildValue("l", (long) spawnval);
3125}
3126
3127
3128PyDoc_STRVAR(posix_spawnvpe__doc__,
3129"spawnvpe(mode, file, args, env)\n\n\
3130Execute the program 'file' in a new process, using the environment\n\
3131search path to find the file.\n\
3132\n\
3133 mode: mode of process creation\n\
3134 file: executable file name\n\
3135 args: tuple or list of arguments\n\
3136 env: dictionary of strings mapping to strings");
3137
3138static PyObject *
3139posix_spawnvpe(PyObject *self, PyObject *args)
3140{
3141 char *path;
3142 PyObject *argv, *env;
3143 char **argvlist;
3144 char **envlist;
3145 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3146 int mode, i, pos, argc, envc;
3147 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003148 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003149 int lastarg = 0;
3150
3151 /* spawnvpe has four arguments: (mode, path, argv, env), where
3152 argv is a list or tuple of strings and env is a dictionary
3153 like posix.environ. */
3154
3155 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3156 Py_FileSystemDefaultEncoding,
3157 &path, &argv, &env))
3158 return NULL;
3159 if (PyList_Check(argv)) {
3160 argc = PyList_Size(argv);
3161 getitem = PyList_GetItem;
3162 }
3163 else if (PyTuple_Check(argv)) {
3164 argc = PyTuple_Size(argv);
3165 getitem = PyTuple_GetItem;
3166 }
3167 else {
3168 PyErr_SetString(PyExc_TypeError,
3169 "spawnvpe() arg 2 must be a tuple or list");
3170 goto fail_0;
3171 }
3172 if (!PyMapping_Check(env)) {
3173 PyErr_SetString(PyExc_TypeError,
3174 "spawnvpe() arg 3 must be a mapping object");
3175 goto fail_0;
3176 }
3177
3178 argvlist = PyMem_NEW(char *, argc+1);
3179 if (argvlist == NULL) {
3180 PyErr_NoMemory();
3181 goto fail_0;
3182 }
3183 for (i = 0; i < argc; i++) {
3184 if (!PyArg_Parse((*getitem)(argv, i),
3185 "et;spawnvpe() arg 2 must contain only strings",
3186 Py_FileSystemDefaultEncoding,
3187 &argvlist[i]))
3188 {
3189 lastarg = i;
3190 goto fail_1;
3191 }
3192 }
3193 lastarg = argc;
3194 argvlist[argc] = NULL;
3195
3196 i = PyMapping_Size(env);
3197 if (i < 0)
3198 goto fail_1;
3199 envlist = PyMem_NEW(char *, i + 1);
3200 if (envlist == NULL) {
3201 PyErr_NoMemory();
3202 goto fail_1;
3203 }
3204 envc = 0;
3205 keys = PyMapping_Keys(env);
3206 vals = PyMapping_Values(env);
3207 if (!keys || !vals)
3208 goto fail_2;
3209 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3210 PyErr_SetString(PyExc_TypeError,
3211 "spawnvpe(): env.keys() or env.values() is not a list");
3212 goto fail_2;
3213 }
3214
3215 for (pos = 0; pos < i; pos++) {
3216 char *p, *k, *v;
3217 size_t len;
3218
3219 key = PyList_GetItem(keys, pos);
3220 val = PyList_GetItem(vals, pos);
3221 if (!key || !val)
3222 goto fail_2;
3223
3224 if (!PyArg_Parse(
3225 key,
3226 "s;spawnvpe() arg 3 contains a non-string key",
3227 &k) ||
3228 !PyArg_Parse(
3229 val,
3230 "s;spawnvpe() arg 3 contains a non-string value",
3231 &v))
3232 {
3233 goto fail_2;
3234 }
3235 len = PyString_Size(key) + PyString_Size(val) + 2;
3236 p = PyMem_NEW(char, len);
3237 if (p == NULL) {
3238 PyErr_NoMemory();
3239 goto fail_2;
3240 }
3241 PyOS_snprintf(p, len, "%s=%s", k, v);
3242 envlist[envc++] = p;
3243 }
3244 envlist[envc] = 0;
3245
3246 Py_BEGIN_ALLOW_THREADS
3247#if defined(PYCC_GCC)
3248 spawnval = spawnve(mode, path, argvlist, envlist);
3249#else
3250 spawnval = _spawnve(mode, path, argvlist, envlist);
3251#endif
3252 Py_END_ALLOW_THREADS
3253
3254 if (spawnval == -1)
3255 (void) posix_error();
3256 else
3257 res = Py_BuildValue("l", (long) spawnval);
3258
3259 fail_2:
3260 while (--envc >= 0)
3261 PyMem_DEL(envlist[envc]);
3262 PyMem_DEL(envlist);
3263 fail_1:
3264 free_string_array(argvlist, lastarg);
3265 Py_XDECREF(vals);
3266 Py_XDECREF(keys);
3267 fail_0:
3268 PyMem_Free(path);
3269 return res;
3270}
3271#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003272#endif /* HAVE_SPAWNV */
3273
3274
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003275#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003276PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003277"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003278Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3279\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003280Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003281
3282static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003283posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003284{
Neal Norwitze241ce82003-02-17 18:17:05 +00003285 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003286 if (pid == -1)
3287 return posix_error();
3288 PyOS_AfterFork();
3289 return PyInt_FromLong((long)pid);
3290}
3291#endif
3292
3293
Guido van Rossumad0ee831995-03-01 10:34:45 +00003294#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003295PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003296"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003298Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003299
Barry Warsaw53699e91996-12-10 23:23:01 +00003300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003301posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003302{
Neal Norwitze241ce82003-02-17 18:17:05 +00003303 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003304 if (pid == -1)
3305 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003306 if (pid == 0)
3307 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003308 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003309}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003310#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003311
Neal Norwitzb59798b2003-03-21 01:43:31 +00003312/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003313/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3314#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003315#define DEV_PTY_FILE "/dev/ptc"
3316#define HAVE_DEV_PTMX
3317#else
3318#define DEV_PTY_FILE "/dev/ptmx"
3319#endif
3320
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003321#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003322#ifdef HAVE_PTY_H
3323#include <pty.h>
3324#else
3325#ifdef HAVE_LIBUTIL_H
3326#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003327#endif /* HAVE_LIBUTIL_H */
3328#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003329#ifdef HAVE_STROPTS_H
3330#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003331#endif
3332#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003333
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003334#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003335PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003336"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003337Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003338
3339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003340posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003341{
3342 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003343#ifndef HAVE_OPENPTY
3344 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003345#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003346#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003347 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003348#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003349 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003350#endif
3351#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003352
Thomas Wouters70c21a12000-07-14 14:28:33 +00003353#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003354 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3355 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003356#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003357 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3358 if (slave_name == NULL)
3359 return posix_error();
3360
3361 slave_fd = open(slave_name, O_RDWR);
3362 if (slave_fd < 0)
3363 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003364#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003365 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003366 if (master_fd < 0)
3367 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003368 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003369 /* change permission of slave */
3370 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003371 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003372 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003373 }
3374 /* unlock slave */
3375 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003376 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003377 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003378 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003379 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003380 slave_name = ptsname(master_fd); /* get name of slave */
3381 if (slave_name == NULL)
3382 return posix_error();
3383 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3384 if (slave_fd < 0)
3385 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003386#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003387 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3388 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003389#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003390 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003391#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003392#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003393#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003394
Fred Drake8cef4cf2000-06-28 16:40:38 +00003395 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003396
Fred Drake8cef4cf2000-06-28 16:40:38 +00003397}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003398#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003399
3400#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003401PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003402"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003403Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3404Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003405To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003406
3407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003408posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003409{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003410 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003411
Fred Drake8cef4cf2000-06-28 16:40:38 +00003412 pid = forkpty(&master_fd, NULL, NULL, NULL);
3413 if (pid == -1)
3414 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003415 if (pid == 0)
3416 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003417 return Py_BuildValue("(ii)", pid, master_fd);
3418}
3419#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003420
Guido van Rossumad0ee831995-03-01 10:34:45 +00003421#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003422PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003423"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003424Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003425
Barry Warsaw53699e91996-12-10 23:23:01 +00003426static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003427posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003428{
Barry Warsaw53699e91996-12-10 23:23:01 +00003429 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003430}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003431#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Guido van Rossumad0ee831995-03-01 10:34:45 +00003434#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003436"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003437Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003438
Barry Warsaw53699e91996-12-10 23:23:01 +00003439static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003440posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003441{
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003443}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003444#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
Guido van Rossumad0ee831995-03-01 10:34:45 +00003447#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003448PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003449"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003450Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003451
Barry Warsaw53699e91996-12-10 23:23:01 +00003452static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003453posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003454{
Barry Warsaw53699e91996-12-10 23:23:01 +00003455 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003456}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003457#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003458
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003460PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003461"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003462Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003463
Barry Warsaw53699e91996-12-10 23:23:01 +00003464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003465posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003466{
Barry Warsaw53699e91996-12-10 23:23:01 +00003467 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003468}
3469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003470
Fred Drakec9680921999-12-13 16:37:25 +00003471#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003472PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003473"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003474Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003475
3476static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003477posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003478{
3479 PyObject *result = NULL;
3480
Fred Drakec9680921999-12-13 16:37:25 +00003481#ifdef NGROUPS_MAX
3482#define MAX_GROUPS NGROUPS_MAX
3483#else
3484 /* defined to be 16 on Solaris7, so this should be a small number */
3485#define MAX_GROUPS 64
3486#endif
3487 gid_t grouplist[MAX_GROUPS];
3488 int n;
3489
3490 n = getgroups(MAX_GROUPS, grouplist);
3491 if (n < 0)
3492 posix_error();
3493 else {
3494 result = PyList_New(n);
3495 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003496 int i;
3497 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003498 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003499 if (o == NULL) {
3500 Py_DECREF(result);
3501 result = NULL;
3502 break;
3503 }
3504 PyList_SET_ITEM(result, i, o);
3505 }
3506 }
3507 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003508
Fred Drakec9680921999-12-13 16:37:25 +00003509 return result;
3510}
3511#endif
3512
Martin v. Löwis606edc12002-06-13 21:09:11 +00003513#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003514PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003515"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003516Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003517
3518static PyObject *
3519posix_getpgid(PyObject *self, PyObject *args)
3520{
3521 int pid, pgid;
3522 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3523 return NULL;
3524 pgid = getpgid(pid);
3525 if (pgid < 0)
3526 return posix_error();
3527 return PyInt_FromLong((long)pgid);
3528}
3529#endif /* HAVE_GETPGID */
3530
3531
Guido van Rossumb6775db1994-08-01 11:34:53 +00003532#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003533PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003534"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003536
Barry Warsaw53699e91996-12-10 23:23:01 +00003537static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003538posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003539{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003540#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003541 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003542#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003543 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003544#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003545}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003546#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003548
Guido van Rossumb6775db1994-08-01 11:34:53 +00003549#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003550PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003551"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003552Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003553
Barry Warsaw53699e91996-12-10 23:23:01 +00003554static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003555posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003556{
Guido van Rossum64933891994-10-20 21:56:42 +00003557#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003558 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003559#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003560 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003561#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003562 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003563 Py_INCREF(Py_None);
3564 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003565}
3566
Guido van Rossumb6775db1994-08-01 11:34:53 +00003567#endif /* HAVE_SETPGRP */
3568
Guido van Rossumad0ee831995-03-01 10:34:45 +00003569#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003570PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003571"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003572Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003573
Barry Warsaw53699e91996-12-10 23:23:01 +00003574static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003575posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003576{
Barry Warsaw53699e91996-12-10 23:23:01 +00003577 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003578}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003579#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003581
Fred Drake12c6e2d1999-12-14 21:25:03 +00003582#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003583PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003584"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003585Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003586
3587static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003588posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003589{
Neal Norwitze241ce82003-02-17 18:17:05 +00003590 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003591 char *name;
3592 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003593
Fred Drakea30680b2000-12-06 21:24:28 +00003594 errno = 0;
3595 name = getlogin();
3596 if (name == NULL) {
3597 if (errno)
3598 posix_error();
3599 else
3600 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003601 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003602 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003603 else
3604 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003605 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003606
Fred Drake12c6e2d1999-12-14 21:25:03 +00003607 return result;
3608}
3609#endif
3610
Guido van Rossumad0ee831995-03-01 10:34:45 +00003611#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003612PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003613"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003614Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003615
Barry Warsaw53699e91996-12-10 23:23:01 +00003616static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003617posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003618{
Barry Warsaw53699e91996-12-10 23:23:01 +00003619 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003620}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003621#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003623
Guido van Rossumad0ee831995-03-01 10:34:45 +00003624#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003625PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003626"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003627Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003628
Barry Warsaw53699e91996-12-10 23:23:01 +00003629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003630posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003631{
3632 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003633 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003634 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003635#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003636 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3637 APIRET rc;
3638 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003639 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003640
3641 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3642 APIRET rc;
3643 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003644 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003645
3646 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003647 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003648#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003649 if (kill(pid, sig) == -1)
3650 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003651#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003652 Py_INCREF(Py_None);
3653 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003654}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003655#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003656
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003657#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003658PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003659"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003660Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003661
3662static PyObject *
3663posix_killpg(PyObject *self, PyObject *args)
3664{
3665 int pgid, sig;
3666 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3667 return NULL;
3668 if (killpg(pgid, sig) == -1)
3669 return posix_error();
3670 Py_INCREF(Py_None);
3671 return Py_None;
3672}
3673#endif
3674
Guido van Rossumc0125471996-06-28 18:55:32 +00003675#ifdef HAVE_PLOCK
3676
3677#ifdef HAVE_SYS_LOCK_H
3678#include <sys/lock.h>
3679#endif
3680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003681PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003682"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003683Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003684
Barry Warsaw53699e91996-12-10 23:23:01 +00003685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003686posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003687{
3688 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003689 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003690 return NULL;
3691 if (plock(op) == -1)
3692 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003693 Py_INCREF(Py_None);
3694 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003695}
3696#endif
3697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003698
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003699#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003700PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003701"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003702Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003703
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003704#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003705#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003706static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003707async_system(const char *command)
3708{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003709 char errormsg[256], args[1024];
3710 RESULTCODES rcodes;
3711 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003712
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003713 char *shell = getenv("COMSPEC");
3714 if (!shell)
3715 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003716
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003717 /* avoid overflowing the argument buffer */
3718 if (strlen(shell) + 3 + strlen(command) >= 1024)
3719 return ERROR_NOT_ENOUGH_MEMORY
3720
3721 args[0] = '\0';
3722 strcat(args, shell);
3723 strcat(args, "/c ");
3724 strcat(args, command);
3725
3726 /* execute asynchronously, inheriting the environment */
3727 rc = DosExecPgm(errormsg,
3728 sizeof(errormsg),
3729 EXEC_ASYNC,
3730 args,
3731 NULL,
3732 &rcodes,
3733 shell);
3734 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003735}
3736
Guido van Rossumd48f2521997-12-05 22:19:34 +00003737static FILE *
3738popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003739{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003740 int oldfd, tgtfd;
3741 HFILE pipeh[2];
3742 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003743
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003744 /* mode determines which of stdin or stdout is reconnected to
3745 * the pipe to the child
3746 */
3747 if (strchr(mode, 'r') != NULL) {
3748 tgt_fd = 1; /* stdout */
3749 } else if (strchr(mode, 'w')) {
3750 tgt_fd = 0; /* stdin */
3751 } else {
3752 *err = ERROR_INVALID_ACCESS;
3753 return NULL;
3754 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003755
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003756 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003757 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3758 *err = rc;
3759 return NULL;
3760 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003761
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003762 /* prevent other threads accessing stdio */
3763 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003764
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003765 /* reconnect stdio and execute child */
3766 oldfd = dup(tgtfd);
3767 close(tgtfd);
3768 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3769 DosClose(pipeh[tgtfd]);
3770 rc = async_system(command);
3771 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003772
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003773 /* restore stdio */
3774 dup2(oldfd, tgtfd);
3775 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003776
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003777 /* allow other threads access to stdio */
3778 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003779
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003780 /* if execution of child was successful return file stream */
3781 if (rc == NO_ERROR)
3782 return fdopen(pipeh[1 - tgtfd], mode);
3783 else {
3784 DosClose(pipeh[1 - tgtfd]);
3785 *err = rc;
3786 return NULL;
3787 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003788}
3789
3790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003791posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003792{
3793 char *name;
3794 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003795 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003796 FILE *fp;
3797 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003798 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003799 return NULL;
3800 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003801 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003802 Py_END_ALLOW_THREADS
3803 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003804 return os2_error(err);
3805
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003806 f = PyFile_FromFile(fp, name, mode, fclose);
3807 if (f != NULL)
3808 PyFile_SetBufSize(f, bufsize);
3809 return f;
3810}
3811
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003812#elif defined(PYCC_GCC)
3813
3814/* standard posix version of popen() support */
3815static PyObject *
3816posix_popen(PyObject *self, PyObject *args)
3817{
3818 char *name;
3819 char *mode = "r";
3820 int bufsize = -1;
3821 FILE *fp;
3822 PyObject *f;
3823 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3824 return NULL;
3825 Py_BEGIN_ALLOW_THREADS
3826 fp = popen(name, mode);
3827 Py_END_ALLOW_THREADS
3828 if (fp == NULL)
3829 return posix_error();
3830 f = PyFile_FromFile(fp, name, mode, pclose);
3831 if (f != NULL)
3832 PyFile_SetBufSize(f, bufsize);
3833 return f;
3834}
3835
3836/* fork() under OS/2 has lots'o'warts
3837 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3838 * most of this code is a ripoff of the win32 code, but using the
3839 * capabilities of EMX's C library routines
3840 */
3841
3842/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3843#define POPEN_1 1
3844#define POPEN_2 2
3845#define POPEN_3 3
3846#define POPEN_4 4
3847
3848static PyObject *_PyPopen(char *, int, int, int);
3849static int _PyPclose(FILE *file);
3850
3851/*
3852 * Internal dictionary mapping popen* file pointers to process handles,
3853 * for use when retrieving the process exit code. See _PyPclose() below
3854 * for more information on this dictionary's use.
3855 */
3856static PyObject *_PyPopenProcs = NULL;
3857
3858/* os2emx version of popen2()
3859 *
3860 * The result of this function is a pipe (file) connected to the
3861 * process's stdin, and a pipe connected to the process's stdout.
3862 */
3863
3864static PyObject *
3865os2emx_popen2(PyObject *self, PyObject *args)
3866{
3867 PyObject *f;
3868 int tm=0;
3869
3870 char *cmdstring;
3871 char *mode = "t";
3872 int bufsize = -1;
3873 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3874 return NULL;
3875
3876 if (*mode == 't')
3877 tm = O_TEXT;
3878 else if (*mode != 'b') {
3879 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3880 return NULL;
3881 } else
3882 tm = O_BINARY;
3883
3884 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3885
3886 return f;
3887}
3888
3889/*
3890 * Variation on os2emx.popen2
3891 *
3892 * The result of this function is 3 pipes - the process's stdin,
3893 * stdout and stderr
3894 */
3895
3896static PyObject *
3897os2emx_popen3(PyObject *self, PyObject *args)
3898{
3899 PyObject *f;
3900 int tm = 0;
3901
3902 char *cmdstring;
3903 char *mode = "t";
3904 int bufsize = -1;
3905 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3906 return NULL;
3907
3908 if (*mode == 't')
3909 tm = O_TEXT;
3910 else if (*mode != 'b') {
3911 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3912 return NULL;
3913 } else
3914 tm = O_BINARY;
3915
3916 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3917
3918 return f;
3919}
3920
3921/*
3922 * Variation on os2emx.popen2
3923 *
Tim Peters11b23062003-04-23 02:39:17 +00003924 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003925 * and stdout+stderr combined as a single pipe.
3926 */
3927
3928static PyObject *
3929os2emx_popen4(PyObject *self, PyObject *args)
3930{
3931 PyObject *f;
3932 int tm = 0;
3933
3934 char *cmdstring;
3935 char *mode = "t";
3936 int bufsize = -1;
3937 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3938 return NULL;
3939
3940 if (*mode == 't')
3941 tm = O_TEXT;
3942 else if (*mode != 'b') {
3943 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3944 return NULL;
3945 } else
3946 tm = O_BINARY;
3947
3948 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3949
3950 return f;
3951}
3952
3953/* a couple of structures for convenient handling of multiple
3954 * file handles and pipes
3955 */
3956struct file_ref
3957{
3958 int handle;
3959 int flags;
3960};
3961
3962struct pipe_ref
3963{
3964 int rd;
3965 int wr;
3966};
3967
3968/* The following code is derived from the win32 code */
3969
3970static PyObject *
3971_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3972{
3973 struct file_ref stdio[3];
3974 struct pipe_ref p_fd[3];
3975 FILE *p_s[3];
3976 int file_count, i, pipe_err, pipe_pid;
3977 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3978 PyObject *f, *p_f[3];
3979
3980 /* file modes for subsequent fdopen's on pipe handles */
3981 if (mode == O_TEXT)
3982 {
3983 rd_mode = "rt";
3984 wr_mode = "wt";
3985 }
3986 else
3987 {
3988 rd_mode = "rb";
3989 wr_mode = "wb";
3990 }
3991
3992 /* prepare shell references */
3993 if ((shell = getenv("EMXSHELL")) == NULL)
3994 if ((shell = getenv("COMSPEC")) == NULL)
3995 {
3996 errno = ENOENT;
3997 return posix_error();
3998 }
3999
4000 sh_name = _getname(shell);
4001 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4002 opt = "/c";
4003 else
4004 opt = "-c";
4005
4006 /* save current stdio fds + their flags, and set not inheritable */
4007 i = pipe_err = 0;
4008 while (pipe_err >= 0 && i < 3)
4009 {
4010 pipe_err = stdio[i].handle = dup(i);
4011 stdio[i].flags = fcntl(i, F_GETFD, 0);
4012 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4013 i++;
4014 }
4015 if (pipe_err < 0)
4016 {
4017 /* didn't get them all saved - clean up and bail out */
4018 int saved_err = errno;
4019 while (i-- > 0)
4020 {
4021 close(stdio[i].handle);
4022 }
4023 errno = saved_err;
4024 return posix_error();
4025 }
4026
4027 /* create pipe ends */
4028 file_count = 2;
4029 if (n == POPEN_3)
4030 file_count = 3;
4031 i = pipe_err = 0;
4032 while ((pipe_err == 0) && (i < file_count))
4033 pipe_err = pipe((int *)&p_fd[i++]);
4034 if (pipe_err < 0)
4035 {
4036 /* didn't get them all made - clean up and bail out */
4037 while (i-- > 0)
4038 {
4039 close(p_fd[i].wr);
4040 close(p_fd[i].rd);
4041 }
4042 errno = EPIPE;
4043 return posix_error();
4044 }
4045
4046 /* change the actual standard IO streams over temporarily,
4047 * making the retained pipe ends non-inheritable
4048 */
4049 pipe_err = 0;
4050
4051 /* - stdin */
4052 if (dup2(p_fd[0].rd, 0) == 0)
4053 {
4054 close(p_fd[0].rd);
4055 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4056 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4057 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4058 {
4059 close(p_fd[0].wr);
4060 pipe_err = -1;
4061 }
4062 }
4063 else
4064 {
4065 pipe_err = -1;
4066 }
4067
4068 /* - stdout */
4069 if (pipe_err == 0)
4070 {
4071 if (dup2(p_fd[1].wr, 1) == 1)
4072 {
4073 close(p_fd[1].wr);
4074 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4075 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4076 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4077 {
4078 close(p_fd[1].rd);
4079 pipe_err = -1;
4080 }
4081 }
4082 else
4083 {
4084 pipe_err = -1;
4085 }
4086 }
4087
4088 /* - stderr, as required */
4089 if (pipe_err == 0)
4090 switch (n)
4091 {
4092 case POPEN_3:
4093 {
4094 if (dup2(p_fd[2].wr, 2) == 2)
4095 {
4096 close(p_fd[2].wr);
4097 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4098 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4099 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4100 {
4101 close(p_fd[2].rd);
4102 pipe_err = -1;
4103 }
4104 }
4105 else
4106 {
4107 pipe_err = -1;
4108 }
4109 break;
4110 }
4111
4112 case POPEN_4:
4113 {
4114 if (dup2(1, 2) != 2)
4115 {
4116 pipe_err = -1;
4117 }
4118 break;
4119 }
4120 }
4121
4122 /* spawn the child process */
4123 if (pipe_err == 0)
4124 {
4125 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4126 if (pipe_pid == -1)
4127 {
4128 pipe_err = -1;
4129 }
4130 else
4131 {
4132 /* save the PID into the FILE structure
4133 * NOTE: this implementation doesn't actually
4134 * take advantage of this, but do it for
4135 * completeness - AIM Apr01
4136 */
4137 for (i = 0; i < file_count; i++)
4138 p_s[i]->_pid = pipe_pid;
4139 }
4140 }
4141
4142 /* reset standard IO to normal */
4143 for (i = 0; i < 3; i++)
4144 {
4145 dup2(stdio[i].handle, i);
4146 fcntl(i, F_SETFD, stdio[i].flags);
4147 close(stdio[i].handle);
4148 }
4149
4150 /* if any remnant problems, clean up and bail out */
4151 if (pipe_err < 0)
4152 {
4153 for (i = 0; i < 3; i++)
4154 {
4155 close(p_fd[i].rd);
4156 close(p_fd[i].wr);
4157 }
4158 errno = EPIPE;
4159 return posix_error_with_filename(cmdstring);
4160 }
4161
4162 /* build tuple of file objects to return */
4163 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4164 PyFile_SetBufSize(p_f[0], bufsize);
4165 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4166 PyFile_SetBufSize(p_f[1], bufsize);
4167 if (n == POPEN_3)
4168 {
4169 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4170 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004171 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004172 }
4173 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004174 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004175
4176 /*
4177 * Insert the files we've created into the process dictionary
4178 * all referencing the list with the process handle and the
4179 * initial number of files (see description below in _PyPclose).
4180 * Since if _PyPclose later tried to wait on a process when all
4181 * handles weren't closed, it could create a deadlock with the
4182 * child, we spend some energy here to try to ensure that we
4183 * either insert all file handles into the dictionary or none
4184 * at all. It's a little clumsy with the various popen modes
4185 * and variable number of files involved.
4186 */
4187 if (!_PyPopenProcs)
4188 {
4189 _PyPopenProcs = PyDict_New();
4190 }
4191
4192 if (_PyPopenProcs)
4193 {
4194 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4195 int ins_rc[3];
4196
4197 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4198 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4199
4200 procObj = PyList_New(2);
4201 pidObj = PyInt_FromLong((long) pipe_pid);
4202 intObj = PyInt_FromLong((long) file_count);
4203
4204 if (procObj && pidObj && intObj)
4205 {
4206 PyList_SetItem(procObj, 0, pidObj);
4207 PyList_SetItem(procObj, 1, intObj);
4208
4209 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4210 if (fileObj[0])
4211 {
4212 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4213 fileObj[0],
4214 procObj);
4215 }
4216 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4217 if (fileObj[1])
4218 {
4219 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4220 fileObj[1],
4221 procObj);
4222 }
4223 if (file_count >= 3)
4224 {
4225 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4226 if (fileObj[2])
4227 {
4228 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4229 fileObj[2],
4230 procObj);
4231 }
4232 }
4233
4234 if (ins_rc[0] < 0 || !fileObj[0] ||
4235 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4236 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4237 {
4238 /* Something failed - remove any dictionary
4239 * entries that did make it.
4240 */
4241 if (!ins_rc[0] && fileObj[0])
4242 {
4243 PyDict_DelItem(_PyPopenProcs,
4244 fileObj[0]);
4245 }
4246 if (!ins_rc[1] && fileObj[1])
4247 {
4248 PyDict_DelItem(_PyPopenProcs,
4249 fileObj[1]);
4250 }
4251 if (!ins_rc[2] && fileObj[2])
4252 {
4253 PyDict_DelItem(_PyPopenProcs,
4254 fileObj[2]);
4255 }
4256 }
4257 }
Tim Peters11b23062003-04-23 02:39:17 +00004258
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004259 /*
4260 * Clean up our localized references for the dictionary keys
4261 * and value since PyDict_SetItem will Py_INCREF any copies
4262 * that got placed in the dictionary.
4263 */
4264 Py_XDECREF(procObj);
4265 Py_XDECREF(fileObj[0]);
4266 Py_XDECREF(fileObj[1]);
4267 Py_XDECREF(fileObj[2]);
4268 }
4269
4270 /* Child is launched. */
4271 return f;
4272}
4273
4274/*
4275 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4276 * exit code for the child process and return as a result of the close.
4277 *
4278 * This function uses the _PyPopenProcs dictionary in order to map the
4279 * input file pointer to information about the process that was
4280 * originally created by the popen* call that created the file pointer.
4281 * The dictionary uses the file pointer as a key (with one entry
4282 * inserted for each file returned by the original popen* call) and a
4283 * single list object as the value for all files from a single call.
4284 * The list object contains the Win32 process handle at [0], and a file
4285 * count at [1], which is initialized to the total number of file
4286 * handles using that list.
4287 *
4288 * This function closes whichever handle it is passed, and decrements
4289 * the file count in the dictionary for the process handle pointed to
4290 * by this file. On the last close (when the file count reaches zero),
4291 * this function will wait for the child process and then return its
4292 * exit code as the result of the close() operation. This permits the
4293 * files to be closed in any order - it is always the close() of the
4294 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004295 *
4296 * NOTE: This function is currently called with the GIL released.
4297 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004298 */
4299
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004300static int _PyPclose(FILE *file)
4301{
4302 int result;
4303 int exit_code;
4304 int pipe_pid;
4305 PyObject *procObj, *pidObj, *intObj, *fileObj;
4306 int file_count;
4307#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004308 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004309#endif
4310
4311 /* Close the file handle first, to ensure it can't block the
4312 * child from exiting if it's the last handle.
4313 */
4314 result = fclose(file);
4315
4316#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004317 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004318#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004319 if (_PyPopenProcs)
4320 {
4321 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4322 (procObj = PyDict_GetItem(_PyPopenProcs,
4323 fileObj)) != NULL &&
4324 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4325 (intObj = PyList_GetItem(procObj,1)) != NULL)
4326 {
4327 pipe_pid = (int) PyInt_AsLong(pidObj);
4328 file_count = (int) PyInt_AsLong(intObj);
4329
4330 if (file_count > 1)
4331 {
4332 /* Still other files referencing process */
4333 file_count--;
4334 PyList_SetItem(procObj,1,
4335 PyInt_FromLong((long) file_count));
4336 }
4337 else
4338 {
4339 /* Last file for this process */
4340 if (result != EOF &&
4341 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4342 {
4343 /* extract exit status */
4344 if (WIFEXITED(exit_code))
4345 {
4346 result = WEXITSTATUS(exit_code);
4347 }
4348 else
4349 {
4350 errno = EPIPE;
4351 result = -1;
4352 }
4353 }
4354 else
4355 {
4356 /* Indicate failure - this will cause the file object
4357 * to raise an I/O error and translate the last
4358 * error code from errno. We do have a problem with
4359 * last errors that overlap the normal errno table,
4360 * but that's a consistent problem with the file object.
4361 */
4362 result = -1;
4363 }
4364 }
4365
4366 /* Remove this file pointer from dictionary */
4367 PyDict_DelItem(_PyPopenProcs, fileObj);
4368
4369 if (PyDict_Size(_PyPopenProcs) == 0)
4370 {
4371 Py_DECREF(_PyPopenProcs);
4372 _PyPopenProcs = NULL;
4373 }
4374
4375 } /* if object retrieval ok */
4376
4377 Py_XDECREF(fileObj);
4378 } /* if _PyPopenProcs */
4379
4380#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004381 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004382#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004383 return result;
4384}
4385
4386#endif /* PYCC_??? */
4387
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004388#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004389
4390/*
4391 * Portable 'popen' replacement for Win32.
4392 *
4393 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4394 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004395 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004396 */
4397
4398#include <malloc.h>
4399#include <io.h>
4400#include <fcntl.h>
4401
4402/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4403#define POPEN_1 1
4404#define POPEN_2 2
4405#define POPEN_3 3
4406#define POPEN_4 4
4407
4408static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004409static int _PyPclose(FILE *file);
4410
4411/*
4412 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004413 * for use when retrieving the process exit code. See _PyPclose() below
4414 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004415 */
4416static PyObject *_PyPopenProcs = NULL;
4417
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004418
4419/* popen that works from a GUI.
4420 *
4421 * The result of this function is a pipe (file) connected to the
4422 * processes stdin or stdout, depending on the requested mode.
4423 */
4424
4425static PyObject *
4426posix_popen(PyObject *self, PyObject *args)
4427{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004428 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004429 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004430
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004431 char *cmdstring;
4432 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004433 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004434 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004435 return NULL;
4436
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004437 if (*mode == 'r')
4438 tm = _O_RDONLY;
4439 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004440 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004441 return NULL;
4442 } else
4443 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004444
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004445 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004446 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004447 return NULL;
4448 }
4449
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004451 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004452 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004453 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004454 else
4455 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4456
4457 return f;
4458}
4459
4460/* Variation on win32pipe.popen
4461 *
4462 * The result of this function is a pipe (file) connected to the
4463 * process's stdin, and a pipe connected to the process's stdout.
4464 */
4465
4466static PyObject *
4467win32_popen2(PyObject *self, PyObject *args)
4468{
4469 PyObject *f;
4470 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004471
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004472 char *cmdstring;
4473 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004474 int bufsize = -1;
4475 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004476 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004477
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004478 if (*mode == 't')
4479 tm = _O_TEXT;
4480 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004481 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 return NULL;
4483 } else
4484 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004485
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004486 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004487 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004488 return NULL;
4489 }
4490
4491 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004492
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004493 return f;
4494}
4495
4496/*
4497 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004498 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004499 * The result of this function is 3 pipes - the process's stdin,
4500 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004501 */
4502
4503static PyObject *
4504win32_popen3(PyObject *self, PyObject *args)
4505{
4506 PyObject *f;
4507 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004508
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004509 char *cmdstring;
4510 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004511 int bufsize = -1;
4512 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004513 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004514
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004515 if (*mode == 't')
4516 tm = _O_TEXT;
4517 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004518 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004519 return NULL;
4520 } else
4521 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004522
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004523 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004524 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004525 return NULL;
4526 }
4527
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004528 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004529
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004530 return f;
4531}
4532
4533/*
4534 * Variation on win32pipe.popen
4535 *
Tim Peters5aa91602002-01-30 05:46:57 +00004536 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004537 * and stdout+stderr combined as a single pipe.
4538 */
4539
4540static PyObject *
4541win32_popen4(PyObject *self, PyObject *args)
4542{
4543 PyObject *f;
4544 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004545
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004546 char *cmdstring;
4547 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004548 int bufsize = -1;
4549 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004551
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004552 if (*mode == 't')
4553 tm = _O_TEXT;
4554 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004555 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004556 return NULL;
4557 } else
4558 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004559
4560 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004561 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004562 return NULL;
4563 }
4564
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004565 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004566
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 return f;
4568}
4569
Mark Hammond08501372001-01-31 07:30:29 +00004570static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004571_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004572 HANDLE hStdin,
4573 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004574 HANDLE hStderr,
4575 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004576{
4577 PROCESS_INFORMATION piProcInfo;
4578 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004579 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004580 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004581 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004582 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004583 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004584
4585 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004586 char *comshell;
4587
Tim Peters92e4dd82002-10-05 01:47:34 +00004588 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004590 /* x < i, so x fits into an integer */
4591 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004592
4593 /* Explicitly check if we are using COMMAND.COM. If we are
4594 * then use the w9xpopen hack.
4595 */
4596 comshell = s1 + x;
4597 while (comshell >= s1 && *comshell != '\\')
4598 --comshell;
4599 ++comshell;
4600
4601 if (GetVersion() < 0x80000000 &&
4602 _stricmp(comshell, "command.com") != 0) {
4603 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004604 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004605 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004606 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004607 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004608 }
4609 else {
4610 /*
Tim Peters402d5982001-08-27 06:37:48 +00004611 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4612 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 */
Mark Hammond08501372001-01-31 07:30:29 +00004614 char modulepath[_MAX_PATH];
4615 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004616 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004617 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004618 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004619 x = i+1;
4620 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004621 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004622 strncat(modulepath,
4623 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004624 (sizeof(modulepath)/sizeof(modulepath[0]))
4625 -strlen(modulepath));
4626 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004627 /* Eeek - file-not-found - possibly an embedding
4628 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004629 */
Tim Peters5aa91602002-01-30 05:46:57 +00004630 strncpy(modulepath,
4631 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004632 sizeof(modulepath)/sizeof(modulepath[0]));
4633 if (modulepath[strlen(modulepath)-1] != '\\')
4634 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004635 strncat(modulepath,
4636 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004637 (sizeof(modulepath)/sizeof(modulepath[0]))
4638 -strlen(modulepath));
4639 /* No where else to look - raise an easily identifiable
4640 error, rather than leaving Windows to report
4641 "file not found" - as the user is probably blissfully
4642 unaware this shim EXE is used, and it will confuse them.
4643 (well, it confused me for a while ;-)
4644 */
4645 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004646 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004647 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004648 "for popen to work with your shell "
4649 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004650 szConsoleSpawn);
4651 return FALSE;
4652 }
4653 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004654 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004655 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004656 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004657
Tim Peters92e4dd82002-10-05 01:47:34 +00004658 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004659 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004660 /* To maintain correct argument passing semantics,
4661 we pass the command-line as it stands, and allow
4662 quoting to be applied. w9xpopen.exe will then
4663 use its argv vector, and re-quote the necessary
4664 args for the ultimate child process.
4665 */
Tim Peters75cdad52001-11-28 22:07:30 +00004666 PyOS_snprintf(
4667 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004668 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004669 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004670 s1,
4671 s3,
4672 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004673 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004674 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004675 dialog:
4676 "Your program accessed mem currently in use at xxx"
4677 and a hopeful warning about the stability of your
4678 system.
4679 Cost is Ctrl+C wont kill children, but anyone
4680 who cares can have a go!
4681 */
4682 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004683 }
4684 }
4685
4686 /* Could be an else here to try cmd.exe / command.com in the path
4687 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004688 else {
Tim Peters402d5982001-08-27 06:37:48 +00004689 PyErr_SetString(PyExc_RuntimeError,
4690 "Cannot locate a COMSPEC environment variable to "
4691 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004692 return FALSE;
4693 }
Tim Peters5aa91602002-01-30 05:46:57 +00004694
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004695 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4696 siStartInfo.cb = sizeof(STARTUPINFO);
4697 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4698 siStartInfo.hStdInput = hStdin;
4699 siStartInfo.hStdOutput = hStdout;
4700 siStartInfo.hStdError = hStderr;
4701 siStartInfo.wShowWindow = SW_HIDE;
4702
4703 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004704 s2,
4705 NULL,
4706 NULL,
4707 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004708 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004709 NULL,
4710 NULL,
4711 &siStartInfo,
4712 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004713 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004714 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004715
Mark Hammondb37a3732000-08-14 04:47:33 +00004716 /* Return process handle */
4717 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004718 return TRUE;
4719 }
Tim Peters402d5982001-08-27 06:37:48 +00004720 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004721 return FALSE;
4722}
4723
4724/* The following code is based off of KB: Q190351 */
4725
4726static PyObject *
4727_PyPopen(char *cmdstring, int mode, int n)
4728{
4729 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4730 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004731 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004732
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004733 SECURITY_ATTRIBUTES saAttr;
4734 BOOL fSuccess;
4735 int fd1, fd2, fd3;
4736 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004737 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004738 PyObject *f;
4739
4740 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4741 saAttr.bInheritHandle = TRUE;
4742 saAttr.lpSecurityDescriptor = NULL;
4743
4744 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4745 return win32_error("CreatePipe", NULL);
4746
4747 /* Create new output read handle and the input write handle. Set
4748 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004749 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 * being created. */
4751 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004752 GetCurrentProcess(), &hChildStdinWrDup, 0,
4753 FALSE,
4754 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004755 if (!fSuccess)
4756 return win32_error("DuplicateHandle", NULL);
4757
4758 /* Close the inheritable version of ChildStdin
4759 that we're using. */
4760 CloseHandle(hChildStdinWr);
4761
4762 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4763 return win32_error("CreatePipe", NULL);
4764
4765 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004766 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4767 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004768 if (!fSuccess)
4769 return win32_error("DuplicateHandle", NULL);
4770
4771 /* Close the inheritable version of ChildStdout
4772 that we're using. */
4773 CloseHandle(hChildStdoutRd);
4774
4775 if (n != POPEN_4) {
4776 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4777 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004778 fSuccess = DuplicateHandle(GetCurrentProcess(),
4779 hChildStderrRd,
4780 GetCurrentProcess(),
4781 &hChildStderrRdDup, 0,
4782 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004783 if (!fSuccess)
4784 return win32_error("DuplicateHandle", NULL);
4785 /* Close the inheritable version of ChildStdErr that we're using. */
4786 CloseHandle(hChildStderrRd);
4787 }
Tim Peters5aa91602002-01-30 05:46:57 +00004788
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004789 switch (n) {
4790 case POPEN_1:
4791 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4792 case _O_WRONLY | _O_TEXT:
4793 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004794 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004795 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004796 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004797 PyFile_SetBufSize(f, 0);
4798 /* We don't care about these pipes anymore, so close them. */
4799 CloseHandle(hChildStdoutRdDup);
4800 CloseHandle(hChildStderrRdDup);
4801 break;
4802
4803 case _O_RDONLY | _O_TEXT:
4804 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004805 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004806 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004807 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004808 PyFile_SetBufSize(f, 0);
4809 /* We don't care about these pipes anymore, so close them. */
4810 CloseHandle(hChildStdinWrDup);
4811 CloseHandle(hChildStderrRdDup);
4812 break;
4813
4814 case _O_RDONLY | _O_BINARY:
4815 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004816 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004818 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004819 PyFile_SetBufSize(f, 0);
4820 /* We don't care about these pipes anymore, so close them. */
4821 CloseHandle(hChildStdinWrDup);
4822 CloseHandle(hChildStderrRdDup);
4823 break;
4824
4825 case _O_WRONLY | _O_BINARY:
4826 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004827 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004828 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004829 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004830 PyFile_SetBufSize(f, 0);
4831 /* We don't care about these pipes anymore, so close them. */
4832 CloseHandle(hChildStdoutRdDup);
4833 CloseHandle(hChildStderrRdDup);
4834 break;
4835 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004836 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004837 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004838
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004839 case POPEN_2:
4840 case POPEN_4:
4841 {
4842 char *m1, *m2;
4843 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004844
Tim Peters7dca21e2002-08-19 00:42:29 +00004845 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004846 m1 = "r";
4847 m2 = "w";
4848 } else {
4849 m1 = "rb";
4850 m2 = "wb";
4851 }
4852
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004853 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004854 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004855 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004856 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004857 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004859 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004860 PyFile_SetBufSize(p2, 0);
4861
4862 if (n != 4)
4863 CloseHandle(hChildStderrRdDup);
4864
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004865 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004866 Py_XDECREF(p1);
4867 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004868 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 break;
4870 }
Tim Peters5aa91602002-01-30 05:46:57 +00004871
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004872 case POPEN_3:
4873 {
4874 char *m1, *m2;
4875 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004876
Tim Peters7dca21e2002-08-19 00:42:29 +00004877 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004878 m1 = "r";
4879 m2 = "w";
4880 } else {
4881 m1 = "rb";
4882 m2 = "wb";
4883 }
4884
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004885 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004886 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004887 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004889 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004890 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004891 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004892 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4893 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004894 PyFile_SetBufSize(p1, 0);
4895 PyFile_SetBufSize(p2, 0);
4896 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004897 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004898 Py_XDECREF(p1);
4899 Py_XDECREF(p2);
4900 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004901 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004902 break;
4903 }
4904 }
4905
4906 if (n == POPEN_4) {
4907 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004908 hChildStdinRd,
4909 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004910 hChildStdoutWr,
4911 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004912 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004913 }
4914 else {
4915 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004916 hChildStdinRd,
4917 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004918 hChildStderrWr,
4919 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004920 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004921 }
4922
Mark Hammondb37a3732000-08-14 04:47:33 +00004923 /*
4924 * Insert the files we've created into the process dictionary
4925 * all referencing the list with the process handle and the
4926 * initial number of files (see description below in _PyPclose).
4927 * Since if _PyPclose later tried to wait on a process when all
4928 * handles weren't closed, it could create a deadlock with the
4929 * child, we spend some energy here to try to ensure that we
4930 * either insert all file handles into the dictionary or none
4931 * at all. It's a little clumsy with the various popen modes
4932 * and variable number of files involved.
4933 */
4934 if (!_PyPopenProcs) {
4935 _PyPopenProcs = PyDict_New();
4936 }
4937
4938 if (_PyPopenProcs) {
4939 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4940 int ins_rc[3];
4941
4942 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4943 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4944
4945 procObj = PyList_New(2);
4946 hProcessObj = PyLong_FromVoidPtr(hProcess);
4947 intObj = PyInt_FromLong(file_count);
4948
4949 if (procObj && hProcessObj && intObj) {
4950 PyList_SetItem(procObj,0,hProcessObj);
4951 PyList_SetItem(procObj,1,intObj);
4952
4953 fileObj[0] = PyLong_FromVoidPtr(f1);
4954 if (fileObj[0]) {
4955 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4956 fileObj[0],
4957 procObj);
4958 }
4959 if (file_count >= 2) {
4960 fileObj[1] = PyLong_FromVoidPtr(f2);
4961 if (fileObj[1]) {
4962 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4963 fileObj[1],
4964 procObj);
4965 }
4966 }
4967 if (file_count >= 3) {
4968 fileObj[2] = PyLong_FromVoidPtr(f3);
4969 if (fileObj[2]) {
4970 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4971 fileObj[2],
4972 procObj);
4973 }
4974 }
4975
4976 if (ins_rc[0] < 0 || !fileObj[0] ||
4977 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4978 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4979 /* Something failed - remove any dictionary
4980 * entries that did make it.
4981 */
4982 if (!ins_rc[0] && fileObj[0]) {
4983 PyDict_DelItem(_PyPopenProcs,
4984 fileObj[0]);
4985 }
4986 if (!ins_rc[1] && fileObj[1]) {
4987 PyDict_DelItem(_PyPopenProcs,
4988 fileObj[1]);
4989 }
4990 if (!ins_rc[2] && fileObj[2]) {
4991 PyDict_DelItem(_PyPopenProcs,
4992 fileObj[2]);
4993 }
4994 }
4995 }
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Mark Hammondb37a3732000-08-14 04:47:33 +00004997 /*
4998 * Clean up our localized references for the dictionary keys
4999 * and value since PyDict_SetItem will Py_INCREF any copies
5000 * that got placed in the dictionary.
5001 */
5002 Py_XDECREF(procObj);
5003 Py_XDECREF(fileObj[0]);
5004 Py_XDECREF(fileObj[1]);
5005 Py_XDECREF(fileObj[2]);
5006 }
5007
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005008 /* Child is launched. Close the parents copy of those pipe
5009 * handles that only the child should have open. You need to
5010 * make sure that no handles to the write end of the output pipe
5011 * are maintained in this process or else the pipe will not close
5012 * when the child process exits and the ReadFile will hang. */
5013
5014 if (!CloseHandle(hChildStdinRd))
5015 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005016
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005017 if (!CloseHandle(hChildStdoutWr))
5018 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005019
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005020 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5021 return win32_error("CloseHandle", NULL);
5022
5023 return f;
5024}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005025
5026/*
5027 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5028 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005029 *
5030 * This function uses the _PyPopenProcs dictionary in order to map the
5031 * input file pointer to information about the process that was
5032 * originally created by the popen* call that created the file pointer.
5033 * The dictionary uses the file pointer as a key (with one entry
5034 * inserted for each file returned by the original popen* call) and a
5035 * single list object as the value for all files from a single call.
5036 * The list object contains the Win32 process handle at [0], and a file
5037 * count at [1], which is initialized to the total number of file
5038 * handles using that list.
5039 *
5040 * This function closes whichever handle it is passed, and decrements
5041 * the file count in the dictionary for the process handle pointed to
5042 * by this file. On the last close (when the file count reaches zero),
5043 * this function will wait for the child process and then return its
5044 * exit code as the result of the close() operation. This permits the
5045 * files to be closed in any order - it is always the close() of the
5046 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005047 *
5048 * NOTE: This function is currently called with the GIL released.
5049 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005050 */
Tim Peters736aa322000-09-01 06:51:24 +00005051
Fredrik Lundh56055a42000-07-23 19:47:12 +00005052static int _PyPclose(FILE *file)
5053{
Fredrik Lundh20318932000-07-26 17:29:12 +00005054 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005055 DWORD exit_code;
5056 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005057 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5058 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005059#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005060 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005061#endif
5062
Fredrik Lundh20318932000-07-26 17:29:12 +00005063 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005064 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005065 */
5066 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005067#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005068 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005069#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005070 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005071 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5072 (procObj = PyDict_GetItem(_PyPopenProcs,
5073 fileObj)) != NULL &&
5074 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5075 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5076
5077 hProcess = PyLong_AsVoidPtr(hProcessObj);
5078 file_count = PyInt_AsLong(intObj);
5079
5080 if (file_count > 1) {
5081 /* Still other files referencing process */
5082 file_count--;
5083 PyList_SetItem(procObj,1,
5084 PyInt_FromLong(file_count));
5085 } else {
5086 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005087 if (result != EOF &&
5088 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5089 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005090 /* Possible truncation here in 16-bit environments, but
5091 * real exit codes are just the lower byte in any event.
5092 */
5093 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005094 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005095 /* Indicate failure - this will cause the file object
5096 * to raise an I/O error and translate the last Win32
5097 * error code from errno. We do have a problem with
5098 * last errors that overlap the normal errno table,
5099 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005100 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005101 if (result != EOF) {
5102 /* If the error wasn't from the fclose(), then
5103 * set errno for the file object error handling.
5104 */
5105 errno = GetLastError();
5106 }
5107 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005108 }
5109
5110 /* Free up the native handle at this point */
5111 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005112 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005113
Mark Hammondb37a3732000-08-14 04:47:33 +00005114 /* Remove this file pointer from dictionary */
5115 PyDict_DelItem(_PyPopenProcs, fileObj);
5116
5117 if (PyDict_Size(_PyPopenProcs) == 0) {
5118 Py_DECREF(_PyPopenProcs);
5119 _PyPopenProcs = NULL;
5120 }
5121
5122 } /* if object retrieval ok */
5123
5124 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005125 } /* if _PyPopenProcs */
5126
Tim Peters736aa322000-09-01 06:51:24 +00005127#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005128 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005129#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005130 return result;
5131}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005132
5133#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005136{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005137 char *name;
5138 char *mode = "r";
5139 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005140 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005141 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005142 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005143 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005144 /* Strip mode of binary or text modifiers */
5145 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5146 mode = "r";
5147 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5148 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005149 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005150 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005151 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005152 if (fp == NULL)
5153 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005154 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005155 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005156 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005157 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005158}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005159
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005161#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005163
Guido van Rossumb6775db1994-08-01 11:34:53 +00005164#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005165PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005166"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167Set the current process's user id.");
5168
Barry Warsaw53699e91996-12-10 23:23:01 +00005169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005170posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005171{
5172 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005174 return NULL;
5175 if (setuid(uid) < 0)
5176 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005177 Py_INCREF(Py_None);
5178 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005179}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005180#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005182
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005183#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005184PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005185"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186Set the current process's effective user id.");
5187
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005188static PyObject *
5189posix_seteuid (PyObject *self, PyObject *args)
5190{
5191 int euid;
5192 if (!PyArg_ParseTuple(args, "i", &euid)) {
5193 return NULL;
5194 } else if (seteuid(euid) < 0) {
5195 return posix_error();
5196 } else {
5197 Py_INCREF(Py_None);
5198 return Py_None;
5199 }
5200}
5201#endif /* HAVE_SETEUID */
5202
5203#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005204PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005205"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206Set the current process's effective group id.");
5207
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005208static PyObject *
5209posix_setegid (PyObject *self, PyObject *args)
5210{
5211 int egid;
5212 if (!PyArg_ParseTuple(args, "i", &egid)) {
5213 return NULL;
5214 } else if (setegid(egid) < 0) {
5215 return posix_error();
5216 } else {
5217 Py_INCREF(Py_None);
5218 return Py_None;
5219 }
5220}
5221#endif /* HAVE_SETEGID */
5222
5223#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005224PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005225"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005226Set the current process's real and effective user ids.");
5227
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005228static PyObject *
5229posix_setreuid (PyObject *self, PyObject *args)
5230{
5231 int ruid, euid;
5232 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5233 return NULL;
5234 } else if (setreuid(ruid, euid) < 0) {
5235 return posix_error();
5236 } else {
5237 Py_INCREF(Py_None);
5238 return Py_None;
5239 }
5240}
5241#endif /* HAVE_SETREUID */
5242
5243#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005245"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Set the current process's real and effective group ids.");
5247
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005248static PyObject *
5249posix_setregid (PyObject *self, PyObject *args)
5250{
5251 int rgid, egid;
5252 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5253 return NULL;
5254 } else if (setregid(rgid, egid) < 0) {
5255 return posix_error();
5256 } else {
5257 Py_INCREF(Py_None);
5258 return Py_None;
5259 }
5260}
5261#endif /* HAVE_SETREGID */
5262
Guido van Rossumb6775db1994-08-01 11:34:53 +00005263#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005264PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005265"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005267
Barry Warsaw53699e91996-12-10 23:23:01 +00005268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005269posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005270{
5271 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005273 return NULL;
5274 if (setgid(gid) < 0)
5275 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005276 Py_INCREF(Py_None);
5277 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005278}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005279#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005280
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005281#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005283"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005284Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005285
5286static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005287posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005288{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005289 int i, len;
5290 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005291
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005292 if (!PySequence_Check(groups)) {
5293 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5294 return NULL;
5295 }
5296 len = PySequence_Size(groups);
5297 if (len > MAX_GROUPS) {
5298 PyErr_SetString(PyExc_ValueError, "too many groups");
5299 return NULL;
5300 }
5301 for(i = 0; i < len; i++) {
5302 PyObject *elem;
5303 elem = PySequence_GetItem(groups, i);
5304 if (!elem)
5305 return NULL;
5306 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005307 if (!PyLong_Check(elem)) {
5308 PyErr_SetString(PyExc_TypeError,
5309 "groups must be integers");
5310 Py_DECREF(elem);
5311 return NULL;
5312 } else {
5313 unsigned long x = PyLong_AsUnsignedLong(elem);
5314 if (PyErr_Occurred()) {
5315 PyErr_SetString(PyExc_TypeError,
5316 "group id too big");
5317 Py_DECREF(elem);
5318 return NULL;
5319 }
5320 grouplist[i] = x;
5321 /* read back the value to see if it fitted in gid_t */
5322 if (grouplist[i] != x) {
5323 PyErr_SetString(PyExc_TypeError,
5324 "group id too big");
5325 Py_DECREF(elem);
5326 return NULL;
5327 }
5328 }
5329 } else {
5330 long x = PyInt_AsLong(elem);
5331 grouplist[i] = x;
5332 if (grouplist[i] != x) {
5333 PyErr_SetString(PyExc_TypeError,
5334 "group id too big");
5335 Py_DECREF(elem);
5336 return NULL;
5337 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005338 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005339 Py_DECREF(elem);
5340 }
5341
5342 if (setgroups(len, grouplist) < 0)
5343 return posix_error();
5344 Py_INCREF(Py_None);
5345 return Py_None;
5346}
5347#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005348
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005349#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005350static PyObject *
5351wait_helper(int pid, int status, struct rusage *ru)
5352{
5353 PyObject *result;
5354 static PyObject *struct_rusage;
5355
5356 if (pid == -1)
5357 return posix_error();
5358
5359 if (struct_rusage == NULL) {
5360 PyObject *m = PyImport_ImportModule("resource");
5361 if (m == NULL)
5362 return NULL;
5363 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5364 Py_DECREF(m);
5365 if (struct_rusage == NULL)
5366 return NULL;
5367 }
5368
5369 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5370 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5371 if (!result)
5372 return NULL;
5373
5374#ifndef doubletime
5375#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5376#endif
5377
5378 PyStructSequence_SET_ITEM(result, 0,
5379 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5380 PyStructSequence_SET_ITEM(result, 1,
5381 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5382#define SET_INT(result, index, value)\
5383 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5384 SET_INT(result, 2, ru->ru_maxrss);
5385 SET_INT(result, 3, ru->ru_ixrss);
5386 SET_INT(result, 4, ru->ru_idrss);
5387 SET_INT(result, 5, ru->ru_isrss);
5388 SET_INT(result, 6, ru->ru_minflt);
5389 SET_INT(result, 7, ru->ru_majflt);
5390 SET_INT(result, 8, ru->ru_nswap);
5391 SET_INT(result, 9, ru->ru_inblock);
5392 SET_INT(result, 10, ru->ru_oublock);
5393 SET_INT(result, 11, ru->ru_msgsnd);
5394 SET_INT(result, 12, ru->ru_msgrcv);
5395 SET_INT(result, 13, ru->ru_nsignals);
5396 SET_INT(result, 14, ru->ru_nvcsw);
5397 SET_INT(result, 15, ru->ru_nivcsw);
5398#undef SET_INT
5399
5400 if (PyErr_Occurred()) {
5401 Py_DECREF(result);
5402 return NULL;
5403 }
5404
Neal Norwitz9b00a562006-03-20 08:47:12 +00005405 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005406}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005407#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005408
5409#ifdef HAVE_WAIT3
5410PyDoc_STRVAR(posix_wait3__doc__,
5411"wait3(options) -> (pid, status, rusage)\n\n\
5412Wait for completion of a child process.");
5413
5414static PyObject *
5415posix_wait3(PyObject *self, PyObject *args)
5416{
5417 int pid, options;
5418 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005419 WAIT_TYPE status;
5420 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005421
5422 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5423 return NULL;
5424
5425 Py_BEGIN_ALLOW_THREADS
5426 pid = wait3(&status, options, &ru);
5427 Py_END_ALLOW_THREADS
5428
Neal Norwitzd5a37542006-03-20 06:48:34 +00005429 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005430}
5431#endif /* HAVE_WAIT3 */
5432
5433#ifdef HAVE_WAIT4
5434PyDoc_STRVAR(posix_wait4__doc__,
5435"wait4(pid, options) -> (pid, status, rusage)\n\n\
5436Wait for completion of a given child process.");
5437
5438static PyObject *
5439posix_wait4(PyObject *self, PyObject *args)
5440{
5441 int pid, options;
5442 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005443 WAIT_TYPE status;
5444 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005445
5446 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5447 return NULL;
5448
5449 Py_BEGIN_ALLOW_THREADS
5450 pid = wait4(pid, &status, options, &ru);
5451 Py_END_ALLOW_THREADS
5452
Neal Norwitzd5a37542006-03-20 06:48:34 +00005453 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005454}
5455#endif /* HAVE_WAIT4 */
5456
Guido van Rossumb6775db1994-08-01 11:34:53 +00005457#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005459"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005460Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005461
Barry Warsaw53699e91996-12-10 23:23:01 +00005462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005463posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005464{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005465 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005466 WAIT_TYPE status;
5467 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005468
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005469 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005470 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005471 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005472 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005473 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005474 if (pid == -1)
5475 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005476
5477 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005478}
5479
Tim Petersab034fa2002-02-01 11:27:43 +00005480#elif defined(HAVE_CWAIT)
5481
5482/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005484"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005486
5487static PyObject *
5488posix_waitpid(PyObject *self, PyObject *args)
5489{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005490 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005491 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005492
5493 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5494 return NULL;
5495 Py_BEGIN_ALLOW_THREADS
5496 pid = _cwait(&status, pid, options);
5497 Py_END_ALLOW_THREADS
5498 if (pid == -1)
5499 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005500
5501 /* shift the status left a byte so this is more like the POSIX waitpid */
5502 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005503}
5504#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Guido van Rossumad0ee831995-03-01 10:34:45 +00005506#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005508"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005509Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005510
Barry Warsaw53699e91996-12-10 23:23:01 +00005511static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005512posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005513{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005514 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005515 WAIT_TYPE status;
5516 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005517
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005518 Py_BEGIN_ALLOW_THREADS
5519 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005520 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005521 if (pid == -1)
5522 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005523
5524 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005525}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005526#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005529PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005530"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005532
Barry Warsaw53699e91996-12-10 23:23:01 +00005533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005534posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005535{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005536#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005537 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005538#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005539#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005540 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005541#else
5542 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5543#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005544#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005545}
5546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005547
Guido van Rossumb6775db1994-08-01 11:34:53 +00005548#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005549PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005550"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005551Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005552
Barry Warsaw53699e91996-12-10 23:23:01 +00005553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005554posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005555{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005556 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005557 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005558 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005559 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005560 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005561 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005562 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005563 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005564 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005565 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005566 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005567}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005568#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Guido van Rossumb6775db1994-08-01 11:34:53 +00005571#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005572PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005573"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005574Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005575
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005577posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005578{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005579 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005580}
5581#endif /* HAVE_SYMLINK */
5582
5583
5584#ifdef HAVE_TIMES
5585#ifndef HZ
5586#define HZ 60 /* Universal constant :-) */
5587#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005588
Guido van Rossumd48f2521997-12-05 22:19:34 +00005589#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5590static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005591system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005592{
5593 ULONG value = 0;
5594
5595 Py_BEGIN_ALLOW_THREADS
5596 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5597 Py_END_ALLOW_THREADS
5598
5599 return value;
5600}
5601
5602static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005603posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005604{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005605 /* Currently Only Uptime is Provided -- Others Later */
5606 return Py_BuildValue("ddddd",
5607 (double)0 /* t.tms_utime / HZ */,
5608 (double)0 /* t.tms_stime / HZ */,
5609 (double)0 /* t.tms_cutime / HZ */,
5610 (double)0 /* t.tms_cstime / HZ */,
5611 (double)system_uptime() / 1000);
5612}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005613#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005614static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005615posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005616{
5617 struct tms t;
5618 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005619 errno = 0;
5620 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005621 if (c == (clock_t) -1)
5622 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005623 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005624 (double)t.tms_utime / HZ,
5625 (double)t.tms_stime / HZ,
5626 (double)t.tms_cutime / HZ,
5627 (double)t.tms_cstime / HZ,
5628 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005629}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005630#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005631#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005632
5633
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005634#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005635#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005636static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005637posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005638{
5639 FILETIME create, exit, kernel, user;
5640 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005641 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005642 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5643 /* The fields of a FILETIME structure are the hi and lo part
5644 of a 64-bit value expressed in 100 nanosecond units.
5645 1e7 is one second in such units; 1e-7 the inverse.
5646 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5647 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005648 return Py_BuildValue(
5649 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005650 (double)(kernel.dwHighDateTime*429.4967296 +
5651 kernel.dwLowDateTime*1e-7),
5652 (double)(user.dwHighDateTime*429.4967296 +
5653 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005654 (double)0,
5655 (double)0,
5656 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005657}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005658#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005659
5660#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005662"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005663Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005664#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005667#ifdef HAVE_GETSID
5668PyDoc_STRVAR(posix_getsid__doc__,
5669"getsid(pid) -> sid\n\n\
5670Call the system call getsid().");
5671
5672static PyObject *
5673posix_getsid(PyObject *self, PyObject *args)
5674{
5675 int pid, sid;
5676 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5677 return NULL;
5678 sid = getsid(pid);
5679 if (sid < 0)
5680 return posix_error();
5681 return PyInt_FromLong((long)sid);
5682}
5683#endif /* HAVE_GETSID */
5684
5685
Guido van Rossumb6775db1994-08-01 11:34:53 +00005686#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005687PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005688"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005690
Barry Warsaw53699e91996-12-10 23:23:01 +00005691static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005692posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005693{
Guido van Rossum687dd131993-05-17 08:34:16 +00005694 if (setsid() < 0)
5695 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005696 Py_INCREF(Py_None);
5697 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005698}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005699#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005700
Guido van Rossumb6775db1994-08-01 11:34:53 +00005701#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005703"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005704Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005705
Barry Warsaw53699e91996-12-10 23:23:01 +00005706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005707posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005708{
5709 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005710 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005711 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005712 if (setpgid(pid, pgrp) < 0)
5713 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005714 Py_INCREF(Py_None);
5715 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005716}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005717#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005718
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005719
Guido van Rossumb6775db1994-08-01 11:34:53 +00005720#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005722"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005724
Barry Warsaw53699e91996-12-10 23:23:01 +00005725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005726posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005727{
5728 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005729 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005730 return NULL;
5731 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005732 if (pgid < 0)
5733 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005734 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005735}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005736#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005737
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005738
Guido van Rossumb6775db1994-08-01 11:34:53 +00005739#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005740PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005741"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005742Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005743
Barry Warsaw53699e91996-12-10 23:23:01 +00005744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005745posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005746{
5747 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005748 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005749 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005750 if (tcsetpgrp(fd, pgid) < 0)
5751 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005752 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005753 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005754}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005755#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005756
Guido van Rossum687dd131993-05-17 08:34:16 +00005757/* Functions acting on file descriptors */
5758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005760"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005762
Barry Warsaw53699e91996-12-10 23:23:01 +00005763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005764posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005765{
Mark Hammondef8b6542001-05-13 08:04:26 +00005766 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005767 int flag;
5768 int mode = 0777;
5769 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005770
5771#ifdef MS_WINDOWS
5772 if (unicode_file_names()) {
5773 PyUnicodeObject *po;
5774 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5775 Py_BEGIN_ALLOW_THREADS
5776 /* PyUnicode_AS_UNICODE OK without thread
5777 lock as it is a simple dereference. */
5778 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5779 Py_END_ALLOW_THREADS
5780 if (fd < 0)
5781 return posix_error();
5782 return PyInt_FromLong((long)fd);
5783 }
5784 /* Drop the argument parsing error as narrow strings
5785 are also valid. */
5786 PyErr_Clear();
5787 }
5788#endif
5789
Tim Peters5aa91602002-01-30 05:46:57 +00005790 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005791 Py_FileSystemDefaultEncoding, &file,
5792 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005793 return NULL;
5794
Barry Warsaw53699e91996-12-10 23:23:01 +00005795 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005796 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005797 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005798 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005799 return posix_error_with_allocated_filename(file);
5800 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005801 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005802}
5803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005805PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005806"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005808
Barry Warsaw53699e91996-12-10 23:23:01 +00005809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005810posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005811{
5812 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005813 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005814 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005815 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005816 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005817 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005818 if (res < 0)
5819 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005820 Py_INCREF(Py_None);
5821 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005822}
5823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005824
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005825PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005826"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005827Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005828
Barry Warsaw53699e91996-12-10 23:23:01 +00005829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005830posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005831{
5832 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005833 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005834 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005835 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005836 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005837 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005838 if (fd < 0)
5839 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005840 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005841}
5842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005845"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005847
Barry Warsaw53699e91996-12-10 23:23:01 +00005848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005849posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005850{
5851 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005852 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005853 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005854 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005855 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005856 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005857 if (res < 0)
5858 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005859 Py_INCREF(Py_None);
5860 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005861}
5862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005865"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005866Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005867
Barry Warsaw53699e91996-12-10 23:23:01 +00005868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005869posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005870{
5871 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005872#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005873 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005874#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005875 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005876#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005877 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005878 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005879 return NULL;
5880#ifdef SEEK_SET
5881 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5882 switch (how) {
5883 case 0: how = SEEK_SET; break;
5884 case 1: how = SEEK_CUR; break;
5885 case 2: how = SEEK_END; break;
5886 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005887#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005888
5889#if !defined(HAVE_LARGEFILE_SUPPORT)
5890 pos = PyInt_AsLong(posobj);
5891#else
5892 pos = PyLong_Check(posobj) ?
5893 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5894#endif
5895 if (PyErr_Occurred())
5896 return NULL;
5897
Barry Warsaw53699e91996-12-10 23:23:01 +00005898 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005899#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005900 res = _lseeki64(fd, pos, how);
5901#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005902 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005903#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005904 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005905 if (res < 0)
5906 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005907
5908#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005909 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005910#else
5911 return PyLong_FromLongLong(res);
5912#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005913}
5914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005915
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005916PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005917"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005918Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005919
Barry Warsaw53699e91996-12-10 23:23:01 +00005920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005921posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005922{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005923 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005924 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005925 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005926 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005927 if (size < 0) {
5928 errno = EINVAL;
5929 return posix_error();
5930 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005931 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005932 if (buffer == NULL)
5933 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005934 Py_BEGIN_ALLOW_THREADS
5935 n = read(fd, PyString_AsString(buffer), size);
5936 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005937 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005938 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005939 return posix_error();
5940 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005941 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005942 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005943 return buffer;
5944}
5945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005946
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005947PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005948"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005949Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005950
Barry Warsaw53699e91996-12-10 23:23:01 +00005951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005952posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005953{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005954 int fd;
5955 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005956 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005957
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005958 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005959 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005960 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005961 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005962 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005963 if (size < 0)
5964 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005965 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005966}
5967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005968
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005969PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005970"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005972
Barry Warsaw53699e91996-12-10 23:23:01 +00005973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005974posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005975{
5976 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005977 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005978 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005979 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005980 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005981#ifdef __VMS
5982 /* on OpenVMS we must ensure that all bytes are written to the file */
5983 fsync(fd);
5984#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005985 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005986 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005987 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005988 if (res != 0) {
5989#ifdef MS_WINDOWS
5990 return win32_error("fstat", NULL);
5991#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005992 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005993#endif
5994 }
Tim Peters5aa91602002-01-30 05:46:57 +00005995
Martin v. Löwis14694662006-02-03 12:54:16 +00005996 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005997}
5998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006000PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006001"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006002Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006003
Barry Warsaw53699e91996-12-10 23:23:01 +00006004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006005posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006006{
Guido van Rossum687dd131993-05-17 08:34:16 +00006007 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006008 char *mode = "r";
6009 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006010 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006011 PyObject *f;
6012 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006013 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006014
Thomas Heller1f043e22002-11-07 16:00:59 +00006015 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6016 PyErr_Format(PyExc_ValueError,
6017 "invalid file mode '%s'", mode);
6018 return NULL;
6019 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006020 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006021#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006022 if (mode[0] == 'a') {
6023 /* try to make sure the O_APPEND flag is set */
6024 int flags;
6025 flags = fcntl(fd, F_GETFL);
6026 if (flags != -1)
6027 fcntl(fd, F_SETFL, flags | O_APPEND);
6028 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006029 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006030 /* restore old mode if fdopen failed */
6031 fcntl(fd, F_SETFL, flags);
6032 } else {
6033 fp = fdopen(fd, mode);
6034 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006035#else
6036 fp = fdopen(fd, mode);
6037#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006038 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006039 if (fp == NULL)
6040 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006041 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006042 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006043 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006044 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006045}
6046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006049Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006051
6052static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006053posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006054{
6055 int fd;
6056 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6057 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006058 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006059}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006060
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006061#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006062PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006063"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006064Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006065
Barry Warsaw53699e91996-12-10 23:23:01 +00006066static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006067posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006068{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006069#if defined(PYOS_OS2)
6070 HFILE read, write;
6071 APIRET rc;
6072
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006073 Py_BEGIN_ALLOW_THREADS
6074 rc = DosCreatePipe( &read, &write, 4096);
6075 Py_END_ALLOW_THREADS
6076 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006077 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006078
6079 return Py_BuildValue("(ii)", read, write);
6080#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006081#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006082 int fds[2];
6083 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006084 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006085 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006086 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006087 if (res != 0)
6088 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006089 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006090#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006091 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006092 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006093 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006094 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006095 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006096 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006097 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006098 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006099 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6100 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006101 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006102#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006103#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006104}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006105#endif /* HAVE_PIPE */
6106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006107
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006108#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006109PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006110"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006111Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006112
Barry Warsaw53699e91996-12-10 23:23:01 +00006113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006114posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006115{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006116 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006117 int mode = 0666;
6118 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006119 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006120 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006121 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006122 res = mkfifo(filename, mode);
6123 Py_END_ALLOW_THREADS
6124 if (res < 0)
6125 return posix_error();
6126 Py_INCREF(Py_None);
6127 return Py_None;
6128}
6129#endif
6130
6131
Neal Norwitz11690112002-07-30 01:08:28 +00006132#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006134"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006135Create a filesystem node (file, device special file or named pipe)\n\
6136named filename. mode specifies both the permissions to use and the\n\
6137type of node to be created, being combined (bitwise OR) with one of\n\
6138S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006139device defines the newly created device special file (probably using\n\
6140os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006141
6142
6143static PyObject *
6144posix_mknod(PyObject *self, PyObject *args)
6145{
6146 char *filename;
6147 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006148 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006149 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006150 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006151 return NULL;
6152 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006153 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006154 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006155 if (res < 0)
6156 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006157 Py_INCREF(Py_None);
6158 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006159}
6160#endif
6161
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006162#ifdef HAVE_DEVICE_MACROS
6163PyDoc_STRVAR(posix_major__doc__,
6164"major(device) -> major number\n\
6165Extracts a device major number from a raw device number.");
6166
6167static PyObject *
6168posix_major(PyObject *self, PyObject *args)
6169{
6170 int device;
6171 if (!PyArg_ParseTuple(args, "i:major", &device))
6172 return NULL;
6173 return PyInt_FromLong((long)major(device));
6174}
6175
6176PyDoc_STRVAR(posix_minor__doc__,
6177"minor(device) -> minor number\n\
6178Extracts a device minor number from a raw device number.");
6179
6180static PyObject *
6181posix_minor(PyObject *self, PyObject *args)
6182{
6183 int device;
6184 if (!PyArg_ParseTuple(args, "i:minor", &device))
6185 return NULL;
6186 return PyInt_FromLong((long)minor(device));
6187}
6188
6189PyDoc_STRVAR(posix_makedev__doc__,
6190"makedev(major, minor) -> device number\n\
6191Composes a raw device number from the major and minor device numbers.");
6192
6193static PyObject *
6194posix_makedev(PyObject *self, PyObject *args)
6195{
6196 int major, minor;
6197 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6198 return NULL;
6199 return PyInt_FromLong((long)makedev(major, minor));
6200}
6201#endif /* device macros */
6202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006203
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006204#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006205PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006206"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006207Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006208
Barry Warsaw53699e91996-12-10 23:23:01 +00006209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006210posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006211{
6212 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006213 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006214 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006215 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006216
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006218 return NULL;
6219
6220#if !defined(HAVE_LARGEFILE_SUPPORT)
6221 length = PyInt_AsLong(lenobj);
6222#else
6223 length = PyLong_Check(lenobj) ?
6224 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6225#endif
6226 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006227 return NULL;
6228
Barry Warsaw53699e91996-12-10 23:23:01 +00006229 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006230 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006231 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006232 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006233 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006234 return NULL;
6235 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006236 Py_INCREF(Py_None);
6237 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006238}
6239#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006240
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006241#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006242PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006243"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006244Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Fred Drake762e2061999-08-26 17:23:54 +00006246/* Save putenv() parameters as values here, so we can collect them when they
6247 * get re-set with another call for the same key. */
6248static PyObject *posix_putenv_garbage;
6249
Tim Peters5aa91602002-01-30 05:46:57 +00006250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006251posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006252{
6253 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006254 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006255 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006256 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006257
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006259 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006260
6261#if defined(PYOS_OS2)
6262 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6263 APIRET rc;
6264
Guido van Rossumd48f2521997-12-05 22:19:34 +00006265 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6266 if (rc != NO_ERROR)
6267 return os2_error(rc);
6268
6269 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6270 APIRET rc;
6271
Guido van Rossumd48f2521997-12-05 22:19:34 +00006272 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6273 if (rc != NO_ERROR)
6274 return os2_error(rc);
6275 } else {
6276#endif
6277
Fred Drake762e2061999-08-26 17:23:54 +00006278 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006279 len = strlen(s1) + strlen(s2) + 2;
6280 /* len includes space for a trailing \0; the size arg to
6281 PyString_FromStringAndSize does not count that */
6282 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006283 if (newstr == NULL)
6284 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006285 newenv = PyString_AS_STRING(newstr);
6286 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6287 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006288 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006289 posix_error();
6290 return NULL;
6291 }
Fred Drake762e2061999-08-26 17:23:54 +00006292 /* Install the first arg and newstr in posix_putenv_garbage;
6293 * this will cause previous value to be collected. This has to
6294 * happen after the real putenv() call because the old value
6295 * was still accessible until then. */
6296 if (PyDict_SetItem(posix_putenv_garbage,
6297 PyTuple_GET_ITEM(args, 0), newstr)) {
6298 /* really not much we can do; just leak */
6299 PyErr_Clear();
6300 }
6301 else {
6302 Py_DECREF(newstr);
6303 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006304
6305#if defined(PYOS_OS2)
6306 }
6307#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006308 Py_INCREF(Py_None);
6309 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006310}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006311#endif /* putenv */
6312
Guido van Rossumc524d952001-10-19 01:31:59 +00006313#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006317
6318static PyObject *
6319posix_unsetenv(PyObject *self, PyObject *args)
6320{
6321 char *s1;
6322
6323 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6324 return NULL;
6325
6326 unsetenv(s1);
6327
6328 /* Remove the key from posix_putenv_garbage;
6329 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006330 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006331 * old value was still accessible until then.
6332 */
6333 if (PyDict_DelItem(posix_putenv_garbage,
6334 PyTuple_GET_ITEM(args, 0))) {
6335 /* really not much we can do; just leak */
6336 PyErr_Clear();
6337 }
6338
6339 Py_INCREF(Py_None);
6340 return Py_None;
6341}
6342#endif /* unsetenv */
6343
Guido van Rossumb6a47161997-09-15 22:54:34 +00006344#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006346"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006348
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006350posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006351{
6352 int code;
6353 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006355 return NULL;
6356 message = strerror(code);
6357 if (message == NULL) {
6358 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006359 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006360 return NULL;
6361 }
6362 return PyString_FromString(message);
6363}
6364#endif /* strerror */
6365
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006366
Guido van Rossumc9641791998-08-04 15:26:23 +00006367#ifdef HAVE_SYS_WAIT_H
6368
Fred Drake106c1a02002-04-23 15:58:02 +00006369#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006370PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006371"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006372Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006373
6374static PyObject *
6375posix_WCOREDUMP(PyObject *self, PyObject *args)
6376{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006377 WAIT_TYPE status;
6378 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006379
Neal Norwitzd5a37542006-03-20 06:48:34 +00006380 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006381 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006382
6383 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006384}
6385#endif /* WCOREDUMP */
6386
6387#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006388PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006389"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006390Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006391job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006392
6393static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006394posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006395{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006396 WAIT_TYPE status;
6397 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006398
Neal Norwitzd5a37542006-03-20 06:48:34 +00006399 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006400 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006401
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006402 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006403}
6404#endif /* WIFCONTINUED */
6405
Guido van Rossumc9641791998-08-04 15:26:23 +00006406#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006407PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006408"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006409Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006410
6411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006412posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006413{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006414 WAIT_TYPE status;
6415 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006416
Neal Norwitzd5a37542006-03-20 06:48:34 +00006417 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006418 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006419
Fred Drake106c1a02002-04-23 15:58:02 +00006420 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006421}
6422#endif /* WIFSTOPPED */
6423
6424#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006426"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006428
6429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006430posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006431{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006432 WAIT_TYPE status;
6433 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006434
Neal Norwitzd5a37542006-03-20 06:48:34 +00006435 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006436 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006437
Fred Drake106c1a02002-04-23 15:58:02 +00006438 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006439}
6440#endif /* WIFSIGNALED */
6441
6442#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006444"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006445Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006446system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006447
6448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006449posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006450{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006451 WAIT_TYPE status;
6452 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006453
Neal Norwitzd5a37542006-03-20 06:48:34 +00006454 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006455 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006456
Fred Drake106c1a02002-04-23 15:58:02 +00006457 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006458}
6459#endif /* WIFEXITED */
6460
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006461#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006462PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006463"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006464Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006465
6466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006467posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006468{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006469 WAIT_TYPE status;
6470 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006471
Neal Norwitzd5a37542006-03-20 06:48:34 +00006472 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006473 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006474
Guido van Rossumc9641791998-08-04 15:26:23 +00006475 return Py_BuildValue("i", WEXITSTATUS(status));
6476}
6477#endif /* WEXITSTATUS */
6478
6479#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006481"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006482Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006483value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006484
6485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006486posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006487{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006488 WAIT_TYPE status;
6489 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006490
Neal Norwitzd5a37542006-03-20 06:48:34 +00006491 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006492 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006493
Guido van Rossumc9641791998-08-04 15:26:23 +00006494 return Py_BuildValue("i", WTERMSIG(status));
6495}
6496#endif /* WTERMSIG */
6497
6498#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006500"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006501Return the signal that stopped the process that provided\n\
6502the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006503
6504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006505posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006506{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006507 WAIT_TYPE status;
6508 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006509
Neal Norwitzd5a37542006-03-20 06:48:34 +00006510 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006511 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006512
Guido van Rossumc9641791998-08-04 15:26:23 +00006513 return Py_BuildValue("i", WSTOPSIG(status));
6514}
6515#endif /* WSTOPSIG */
6516
6517#endif /* HAVE_SYS_WAIT_H */
6518
6519
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006520#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006521#ifdef _SCO_DS
6522/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6523 needed definitions in sys/statvfs.h */
6524#define _SVID3
6525#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006526#include <sys/statvfs.h>
6527
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006528static PyObject*
6529_pystatvfs_fromstructstatvfs(struct statvfs st) {
6530 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6531 if (v == NULL)
6532 return NULL;
6533
6534#if !defined(HAVE_LARGEFILE_SUPPORT)
6535 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6536 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6537 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6538 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6539 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6540 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6541 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6542 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6543 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6544 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6545#else
6546 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6547 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006548 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006549 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006550 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006551 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006552 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006553 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006554 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006555 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006556 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006557 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006558 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006559 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006560 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6561 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6562#endif
6563
6564 return v;
6565}
6566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006568"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006570
6571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006572posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006573{
6574 int fd, res;
6575 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006576
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006577 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006578 return NULL;
6579 Py_BEGIN_ALLOW_THREADS
6580 res = fstatvfs(fd, &st);
6581 Py_END_ALLOW_THREADS
6582 if (res != 0)
6583 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006584
6585 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006586}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006587#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006588
6589
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006590#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006591#include <sys/statvfs.h>
6592
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006593PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006594"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006595Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006596
6597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006598posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006599{
6600 char *path;
6601 int res;
6602 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006603 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006604 return NULL;
6605 Py_BEGIN_ALLOW_THREADS
6606 res = statvfs(path, &st);
6607 Py_END_ALLOW_THREADS
6608 if (res != 0)
6609 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006610
6611 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006612}
6613#endif /* HAVE_STATVFS */
6614
6615
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006616#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006617PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006618"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006619Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006620The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006621or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006622
6623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006624posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006625{
6626 PyObject *result = NULL;
6627 char *dir = NULL;
6628 char *pfx = NULL;
6629 char *name;
6630
6631 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6632 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006633
6634 if (PyErr_Warn(PyExc_RuntimeWarning,
6635 "tempnam is a potential security risk to your program") < 0)
6636 return NULL;
6637
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006638#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006639 name = _tempnam(dir, pfx);
6640#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006641 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006642#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006643 if (name == NULL)
6644 return PyErr_NoMemory();
6645 result = PyString_FromString(name);
6646 free(name);
6647 return result;
6648}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006649#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006650
6651
6652#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006653PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006654"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006655Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006656
6657static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006658posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006659{
6660 FILE *fp;
6661
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006662 fp = tmpfile();
6663 if (fp == NULL)
6664 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006665 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006666}
6667#endif
6668
6669
6670#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006672"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006673Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006674
6675static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006676posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006677{
6678 char buffer[L_tmpnam];
6679 char *name;
6680
Skip Montanaro95618b52001-08-18 18:52:10 +00006681 if (PyErr_Warn(PyExc_RuntimeWarning,
6682 "tmpnam is a potential security risk to your program") < 0)
6683 return NULL;
6684
Greg Wardb48bc172000-03-01 21:51:56 +00006685#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006686 name = tmpnam_r(buffer);
6687#else
6688 name = tmpnam(buffer);
6689#endif
6690 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006691 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006692#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006693 "unexpected NULL from tmpnam_r"
6694#else
6695 "unexpected NULL from tmpnam"
6696#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006697 );
6698 PyErr_SetObject(PyExc_OSError, err);
6699 Py_XDECREF(err);
6700 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006701 }
6702 return PyString_FromString(buffer);
6703}
6704#endif
6705
6706
Fred Drakec9680921999-12-13 16:37:25 +00006707/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6708 * It maps strings representing configuration variable names to
6709 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006710 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006711 * rarely-used constants. There are three separate tables that use
6712 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006713 *
6714 * This code is always included, even if none of the interfaces that
6715 * need it are included. The #if hackery needed to avoid it would be
6716 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006717 */
6718struct constdef {
6719 char *name;
6720 long value;
6721};
6722
Fred Drake12c6e2d1999-12-14 21:25:03 +00006723static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006724conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6725 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006726{
6727 if (PyInt_Check(arg)) {
6728 *valuep = PyInt_AS_LONG(arg);
6729 return 1;
6730 }
6731 if (PyString_Check(arg)) {
6732 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006733 size_t lo = 0;
6734 size_t mid;
6735 size_t hi = tablesize;
6736 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006737 char *confname = PyString_AS_STRING(arg);
6738 while (lo < hi) {
6739 mid = (lo + hi) / 2;
6740 cmp = strcmp(confname, table[mid].name);
6741 if (cmp < 0)
6742 hi = mid;
6743 else if (cmp > 0)
6744 lo = mid + 1;
6745 else {
6746 *valuep = table[mid].value;
6747 return 1;
6748 }
6749 }
6750 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6751 }
6752 else
6753 PyErr_SetString(PyExc_TypeError,
6754 "configuration names must be strings or integers");
6755 return 0;
6756}
6757
6758
6759#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6760static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006761#ifdef _PC_ABI_AIO_XFER_MAX
6762 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6763#endif
6764#ifdef _PC_ABI_ASYNC_IO
6765 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6766#endif
Fred Drakec9680921999-12-13 16:37:25 +00006767#ifdef _PC_ASYNC_IO
6768 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6769#endif
6770#ifdef _PC_CHOWN_RESTRICTED
6771 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6772#endif
6773#ifdef _PC_FILESIZEBITS
6774 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6775#endif
6776#ifdef _PC_LAST
6777 {"PC_LAST", _PC_LAST},
6778#endif
6779#ifdef _PC_LINK_MAX
6780 {"PC_LINK_MAX", _PC_LINK_MAX},
6781#endif
6782#ifdef _PC_MAX_CANON
6783 {"PC_MAX_CANON", _PC_MAX_CANON},
6784#endif
6785#ifdef _PC_MAX_INPUT
6786 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6787#endif
6788#ifdef _PC_NAME_MAX
6789 {"PC_NAME_MAX", _PC_NAME_MAX},
6790#endif
6791#ifdef _PC_NO_TRUNC
6792 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6793#endif
6794#ifdef _PC_PATH_MAX
6795 {"PC_PATH_MAX", _PC_PATH_MAX},
6796#endif
6797#ifdef _PC_PIPE_BUF
6798 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6799#endif
6800#ifdef _PC_PRIO_IO
6801 {"PC_PRIO_IO", _PC_PRIO_IO},
6802#endif
6803#ifdef _PC_SOCK_MAXBUF
6804 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6805#endif
6806#ifdef _PC_SYNC_IO
6807 {"PC_SYNC_IO", _PC_SYNC_IO},
6808#endif
6809#ifdef _PC_VDISABLE
6810 {"PC_VDISABLE", _PC_VDISABLE},
6811#endif
6812};
6813
Fred Drakec9680921999-12-13 16:37:25 +00006814static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006815conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006816{
6817 return conv_confname(arg, valuep, posix_constants_pathconf,
6818 sizeof(posix_constants_pathconf)
6819 / sizeof(struct constdef));
6820}
6821#endif
6822
6823#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006824PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006825"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006826Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006827If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006828
6829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006830posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006831{
6832 PyObject *result = NULL;
6833 int name, fd;
6834
Fred Drake12c6e2d1999-12-14 21:25:03 +00006835 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6836 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006837 long limit;
6838
6839 errno = 0;
6840 limit = fpathconf(fd, name);
6841 if (limit == -1 && errno != 0)
6842 posix_error();
6843 else
6844 result = PyInt_FromLong(limit);
6845 }
6846 return result;
6847}
6848#endif
6849
6850
6851#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006852PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006853"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006854Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006855If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006856
6857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006858posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006859{
6860 PyObject *result = NULL;
6861 int name;
6862 char *path;
6863
6864 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6865 conv_path_confname, &name)) {
6866 long limit;
6867
6868 errno = 0;
6869 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006870 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006871 if (errno == EINVAL)
6872 /* could be a path or name problem */
6873 posix_error();
6874 else
6875 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006876 }
Fred Drakec9680921999-12-13 16:37:25 +00006877 else
6878 result = PyInt_FromLong(limit);
6879 }
6880 return result;
6881}
6882#endif
6883
6884#ifdef HAVE_CONFSTR
6885static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006886#ifdef _CS_ARCHITECTURE
6887 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6888#endif
6889#ifdef _CS_HOSTNAME
6890 {"CS_HOSTNAME", _CS_HOSTNAME},
6891#endif
6892#ifdef _CS_HW_PROVIDER
6893 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6894#endif
6895#ifdef _CS_HW_SERIAL
6896 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6897#endif
6898#ifdef _CS_INITTAB_NAME
6899 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6900#endif
Fred Drakec9680921999-12-13 16:37:25 +00006901#ifdef _CS_LFS64_CFLAGS
6902 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6903#endif
6904#ifdef _CS_LFS64_LDFLAGS
6905 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6906#endif
6907#ifdef _CS_LFS64_LIBS
6908 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6909#endif
6910#ifdef _CS_LFS64_LINTFLAGS
6911 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6912#endif
6913#ifdef _CS_LFS_CFLAGS
6914 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6915#endif
6916#ifdef _CS_LFS_LDFLAGS
6917 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6918#endif
6919#ifdef _CS_LFS_LIBS
6920 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6921#endif
6922#ifdef _CS_LFS_LINTFLAGS
6923 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6924#endif
Fred Draked86ed291999-12-15 15:34:33 +00006925#ifdef _CS_MACHINE
6926 {"CS_MACHINE", _CS_MACHINE},
6927#endif
Fred Drakec9680921999-12-13 16:37:25 +00006928#ifdef _CS_PATH
6929 {"CS_PATH", _CS_PATH},
6930#endif
Fred Draked86ed291999-12-15 15:34:33 +00006931#ifdef _CS_RELEASE
6932 {"CS_RELEASE", _CS_RELEASE},
6933#endif
6934#ifdef _CS_SRPC_DOMAIN
6935 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6936#endif
6937#ifdef _CS_SYSNAME
6938 {"CS_SYSNAME", _CS_SYSNAME},
6939#endif
6940#ifdef _CS_VERSION
6941 {"CS_VERSION", _CS_VERSION},
6942#endif
Fred Drakec9680921999-12-13 16:37:25 +00006943#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6944 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6945#endif
6946#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6947 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6948#endif
6949#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6950 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6951#endif
6952#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6953 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6954#endif
6955#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6956 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6957#endif
6958#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6959 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6960#endif
6961#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6962 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6963#endif
6964#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6965 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6966#endif
6967#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6968 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6969#endif
6970#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6971 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6972#endif
6973#ifdef _CS_XBS5_LP64_OFF64_LIBS
6974 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6975#endif
6976#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6977 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6978#endif
6979#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6980 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6981#endif
6982#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6983 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6984#endif
6985#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6986 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6987#endif
6988#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6989 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6990#endif
Fred Draked86ed291999-12-15 15:34:33 +00006991#ifdef _MIPS_CS_AVAIL_PROCESSORS
6992 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6993#endif
6994#ifdef _MIPS_CS_BASE
6995 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6996#endif
6997#ifdef _MIPS_CS_HOSTID
6998 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6999#endif
7000#ifdef _MIPS_CS_HW_NAME
7001 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7002#endif
7003#ifdef _MIPS_CS_NUM_PROCESSORS
7004 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7005#endif
7006#ifdef _MIPS_CS_OSREL_MAJ
7007 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7008#endif
7009#ifdef _MIPS_CS_OSREL_MIN
7010 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7011#endif
7012#ifdef _MIPS_CS_OSREL_PATCH
7013 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7014#endif
7015#ifdef _MIPS_CS_OS_NAME
7016 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7017#endif
7018#ifdef _MIPS_CS_OS_PROVIDER
7019 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7020#endif
7021#ifdef _MIPS_CS_PROCESSORS
7022 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7023#endif
7024#ifdef _MIPS_CS_SERIAL
7025 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7026#endif
7027#ifdef _MIPS_CS_VENDOR
7028 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7029#endif
Fred Drakec9680921999-12-13 16:37:25 +00007030};
7031
7032static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007033conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007034{
7035 return conv_confname(arg, valuep, posix_constants_confstr,
7036 sizeof(posix_constants_confstr)
7037 / sizeof(struct constdef));
7038}
7039
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007040PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007041"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007042Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007043
7044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007045posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007046{
7047 PyObject *result = NULL;
7048 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007049 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007050
7051 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007052 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007053
Fred Drakec9680921999-12-13 16:37:25 +00007054 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007055 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007056 if (len == 0) {
7057 if (errno) {
7058 posix_error();
7059 }
7060 else {
7061 result = Py_None;
7062 Py_INCREF(Py_None);
7063 }
Fred Drakec9680921999-12-13 16:37:25 +00007064 }
7065 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007066 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00007067 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007068 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00007069 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007070 }
7071 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00007072 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007073 }
7074 }
7075 return result;
7076}
7077#endif
7078
7079
7080#ifdef HAVE_SYSCONF
7081static struct constdef posix_constants_sysconf[] = {
7082#ifdef _SC_2_CHAR_TERM
7083 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7084#endif
7085#ifdef _SC_2_C_BIND
7086 {"SC_2_C_BIND", _SC_2_C_BIND},
7087#endif
7088#ifdef _SC_2_C_DEV
7089 {"SC_2_C_DEV", _SC_2_C_DEV},
7090#endif
7091#ifdef _SC_2_C_VERSION
7092 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7093#endif
7094#ifdef _SC_2_FORT_DEV
7095 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7096#endif
7097#ifdef _SC_2_FORT_RUN
7098 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7099#endif
7100#ifdef _SC_2_LOCALEDEF
7101 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7102#endif
7103#ifdef _SC_2_SW_DEV
7104 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7105#endif
7106#ifdef _SC_2_UPE
7107 {"SC_2_UPE", _SC_2_UPE},
7108#endif
7109#ifdef _SC_2_VERSION
7110 {"SC_2_VERSION", _SC_2_VERSION},
7111#endif
Fred Draked86ed291999-12-15 15:34:33 +00007112#ifdef _SC_ABI_ASYNCHRONOUS_IO
7113 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7114#endif
7115#ifdef _SC_ACL
7116 {"SC_ACL", _SC_ACL},
7117#endif
Fred Drakec9680921999-12-13 16:37:25 +00007118#ifdef _SC_AIO_LISTIO_MAX
7119 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7120#endif
Fred Drakec9680921999-12-13 16:37:25 +00007121#ifdef _SC_AIO_MAX
7122 {"SC_AIO_MAX", _SC_AIO_MAX},
7123#endif
7124#ifdef _SC_AIO_PRIO_DELTA_MAX
7125 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7126#endif
7127#ifdef _SC_ARG_MAX
7128 {"SC_ARG_MAX", _SC_ARG_MAX},
7129#endif
7130#ifdef _SC_ASYNCHRONOUS_IO
7131 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7132#endif
7133#ifdef _SC_ATEXIT_MAX
7134 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7135#endif
Fred Draked86ed291999-12-15 15:34:33 +00007136#ifdef _SC_AUDIT
7137 {"SC_AUDIT", _SC_AUDIT},
7138#endif
Fred Drakec9680921999-12-13 16:37:25 +00007139#ifdef _SC_AVPHYS_PAGES
7140 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7141#endif
7142#ifdef _SC_BC_BASE_MAX
7143 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7144#endif
7145#ifdef _SC_BC_DIM_MAX
7146 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7147#endif
7148#ifdef _SC_BC_SCALE_MAX
7149 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7150#endif
7151#ifdef _SC_BC_STRING_MAX
7152 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7153#endif
Fred Draked86ed291999-12-15 15:34:33 +00007154#ifdef _SC_CAP
7155 {"SC_CAP", _SC_CAP},
7156#endif
Fred Drakec9680921999-12-13 16:37:25 +00007157#ifdef _SC_CHARCLASS_NAME_MAX
7158 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7159#endif
7160#ifdef _SC_CHAR_BIT
7161 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7162#endif
7163#ifdef _SC_CHAR_MAX
7164 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7165#endif
7166#ifdef _SC_CHAR_MIN
7167 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7168#endif
7169#ifdef _SC_CHILD_MAX
7170 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7171#endif
7172#ifdef _SC_CLK_TCK
7173 {"SC_CLK_TCK", _SC_CLK_TCK},
7174#endif
7175#ifdef _SC_COHER_BLKSZ
7176 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7177#endif
7178#ifdef _SC_COLL_WEIGHTS_MAX
7179 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7180#endif
7181#ifdef _SC_DCACHE_ASSOC
7182 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7183#endif
7184#ifdef _SC_DCACHE_BLKSZ
7185 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7186#endif
7187#ifdef _SC_DCACHE_LINESZ
7188 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7189#endif
7190#ifdef _SC_DCACHE_SZ
7191 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7192#endif
7193#ifdef _SC_DCACHE_TBLKSZ
7194 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7195#endif
7196#ifdef _SC_DELAYTIMER_MAX
7197 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7198#endif
7199#ifdef _SC_EQUIV_CLASS_MAX
7200 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7201#endif
7202#ifdef _SC_EXPR_NEST_MAX
7203 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7204#endif
7205#ifdef _SC_FSYNC
7206 {"SC_FSYNC", _SC_FSYNC},
7207#endif
7208#ifdef _SC_GETGR_R_SIZE_MAX
7209 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7210#endif
7211#ifdef _SC_GETPW_R_SIZE_MAX
7212 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7213#endif
7214#ifdef _SC_ICACHE_ASSOC
7215 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7216#endif
7217#ifdef _SC_ICACHE_BLKSZ
7218 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7219#endif
7220#ifdef _SC_ICACHE_LINESZ
7221 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7222#endif
7223#ifdef _SC_ICACHE_SZ
7224 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7225#endif
Fred Draked86ed291999-12-15 15:34:33 +00007226#ifdef _SC_INF
7227 {"SC_INF", _SC_INF},
7228#endif
Fred Drakec9680921999-12-13 16:37:25 +00007229#ifdef _SC_INT_MAX
7230 {"SC_INT_MAX", _SC_INT_MAX},
7231#endif
7232#ifdef _SC_INT_MIN
7233 {"SC_INT_MIN", _SC_INT_MIN},
7234#endif
7235#ifdef _SC_IOV_MAX
7236 {"SC_IOV_MAX", _SC_IOV_MAX},
7237#endif
Fred Draked86ed291999-12-15 15:34:33 +00007238#ifdef _SC_IP_SECOPTS
7239 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7240#endif
Fred Drakec9680921999-12-13 16:37:25 +00007241#ifdef _SC_JOB_CONTROL
7242 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7243#endif
Fred Draked86ed291999-12-15 15:34:33 +00007244#ifdef _SC_KERN_POINTERS
7245 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7246#endif
7247#ifdef _SC_KERN_SIM
7248 {"SC_KERN_SIM", _SC_KERN_SIM},
7249#endif
Fred Drakec9680921999-12-13 16:37:25 +00007250#ifdef _SC_LINE_MAX
7251 {"SC_LINE_MAX", _SC_LINE_MAX},
7252#endif
7253#ifdef _SC_LOGIN_NAME_MAX
7254 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7255#endif
7256#ifdef _SC_LOGNAME_MAX
7257 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7258#endif
7259#ifdef _SC_LONG_BIT
7260 {"SC_LONG_BIT", _SC_LONG_BIT},
7261#endif
Fred Draked86ed291999-12-15 15:34:33 +00007262#ifdef _SC_MAC
7263 {"SC_MAC", _SC_MAC},
7264#endif
Fred Drakec9680921999-12-13 16:37:25 +00007265#ifdef _SC_MAPPED_FILES
7266 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7267#endif
7268#ifdef _SC_MAXPID
7269 {"SC_MAXPID", _SC_MAXPID},
7270#endif
7271#ifdef _SC_MB_LEN_MAX
7272 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7273#endif
7274#ifdef _SC_MEMLOCK
7275 {"SC_MEMLOCK", _SC_MEMLOCK},
7276#endif
7277#ifdef _SC_MEMLOCK_RANGE
7278 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7279#endif
7280#ifdef _SC_MEMORY_PROTECTION
7281 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7282#endif
7283#ifdef _SC_MESSAGE_PASSING
7284 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7285#endif
Fred Draked86ed291999-12-15 15:34:33 +00007286#ifdef _SC_MMAP_FIXED_ALIGNMENT
7287 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7288#endif
Fred Drakec9680921999-12-13 16:37:25 +00007289#ifdef _SC_MQ_OPEN_MAX
7290 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7291#endif
7292#ifdef _SC_MQ_PRIO_MAX
7293 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7294#endif
Fred Draked86ed291999-12-15 15:34:33 +00007295#ifdef _SC_NACLS_MAX
7296 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7297#endif
Fred Drakec9680921999-12-13 16:37:25 +00007298#ifdef _SC_NGROUPS_MAX
7299 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7300#endif
7301#ifdef _SC_NL_ARGMAX
7302 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7303#endif
7304#ifdef _SC_NL_LANGMAX
7305 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7306#endif
7307#ifdef _SC_NL_MSGMAX
7308 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7309#endif
7310#ifdef _SC_NL_NMAX
7311 {"SC_NL_NMAX", _SC_NL_NMAX},
7312#endif
7313#ifdef _SC_NL_SETMAX
7314 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7315#endif
7316#ifdef _SC_NL_TEXTMAX
7317 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7318#endif
7319#ifdef _SC_NPROCESSORS_CONF
7320 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7321#endif
7322#ifdef _SC_NPROCESSORS_ONLN
7323 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7324#endif
Fred Draked86ed291999-12-15 15:34:33 +00007325#ifdef _SC_NPROC_CONF
7326 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7327#endif
7328#ifdef _SC_NPROC_ONLN
7329 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7330#endif
Fred Drakec9680921999-12-13 16:37:25 +00007331#ifdef _SC_NZERO
7332 {"SC_NZERO", _SC_NZERO},
7333#endif
7334#ifdef _SC_OPEN_MAX
7335 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7336#endif
7337#ifdef _SC_PAGESIZE
7338 {"SC_PAGESIZE", _SC_PAGESIZE},
7339#endif
7340#ifdef _SC_PAGE_SIZE
7341 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7342#endif
7343#ifdef _SC_PASS_MAX
7344 {"SC_PASS_MAX", _SC_PASS_MAX},
7345#endif
7346#ifdef _SC_PHYS_PAGES
7347 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7348#endif
7349#ifdef _SC_PII
7350 {"SC_PII", _SC_PII},
7351#endif
7352#ifdef _SC_PII_INTERNET
7353 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7354#endif
7355#ifdef _SC_PII_INTERNET_DGRAM
7356 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7357#endif
7358#ifdef _SC_PII_INTERNET_STREAM
7359 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7360#endif
7361#ifdef _SC_PII_OSI
7362 {"SC_PII_OSI", _SC_PII_OSI},
7363#endif
7364#ifdef _SC_PII_OSI_CLTS
7365 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7366#endif
7367#ifdef _SC_PII_OSI_COTS
7368 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7369#endif
7370#ifdef _SC_PII_OSI_M
7371 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7372#endif
7373#ifdef _SC_PII_SOCKET
7374 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7375#endif
7376#ifdef _SC_PII_XTI
7377 {"SC_PII_XTI", _SC_PII_XTI},
7378#endif
7379#ifdef _SC_POLL
7380 {"SC_POLL", _SC_POLL},
7381#endif
7382#ifdef _SC_PRIORITIZED_IO
7383 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7384#endif
7385#ifdef _SC_PRIORITY_SCHEDULING
7386 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7387#endif
7388#ifdef _SC_REALTIME_SIGNALS
7389 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7390#endif
7391#ifdef _SC_RE_DUP_MAX
7392 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7393#endif
7394#ifdef _SC_RTSIG_MAX
7395 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7396#endif
7397#ifdef _SC_SAVED_IDS
7398 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7399#endif
7400#ifdef _SC_SCHAR_MAX
7401 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7402#endif
7403#ifdef _SC_SCHAR_MIN
7404 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7405#endif
7406#ifdef _SC_SELECT
7407 {"SC_SELECT", _SC_SELECT},
7408#endif
7409#ifdef _SC_SEMAPHORES
7410 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7411#endif
7412#ifdef _SC_SEM_NSEMS_MAX
7413 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7414#endif
7415#ifdef _SC_SEM_VALUE_MAX
7416 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7417#endif
7418#ifdef _SC_SHARED_MEMORY_OBJECTS
7419 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7420#endif
7421#ifdef _SC_SHRT_MAX
7422 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7423#endif
7424#ifdef _SC_SHRT_MIN
7425 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7426#endif
7427#ifdef _SC_SIGQUEUE_MAX
7428 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7429#endif
7430#ifdef _SC_SIGRT_MAX
7431 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7432#endif
7433#ifdef _SC_SIGRT_MIN
7434 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7435#endif
Fred Draked86ed291999-12-15 15:34:33 +00007436#ifdef _SC_SOFTPOWER
7437 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7438#endif
Fred Drakec9680921999-12-13 16:37:25 +00007439#ifdef _SC_SPLIT_CACHE
7440 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7441#endif
7442#ifdef _SC_SSIZE_MAX
7443 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7444#endif
7445#ifdef _SC_STACK_PROT
7446 {"SC_STACK_PROT", _SC_STACK_PROT},
7447#endif
7448#ifdef _SC_STREAM_MAX
7449 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7450#endif
7451#ifdef _SC_SYNCHRONIZED_IO
7452 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7453#endif
7454#ifdef _SC_THREADS
7455 {"SC_THREADS", _SC_THREADS},
7456#endif
7457#ifdef _SC_THREAD_ATTR_STACKADDR
7458 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7459#endif
7460#ifdef _SC_THREAD_ATTR_STACKSIZE
7461 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7462#endif
7463#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7464 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7465#endif
7466#ifdef _SC_THREAD_KEYS_MAX
7467 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7468#endif
7469#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7470 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7471#endif
7472#ifdef _SC_THREAD_PRIO_INHERIT
7473 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7474#endif
7475#ifdef _SC_THREAD_PRIO_PROTECT
7476 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7477#endif
7478#ifdef _SC_THREAD_PROCESS_SHARED
7479 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7480#endif
7481#ifdef _SC_THREAD_SAFE_FUNCTIONS
7482 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7483#endif
7484#ifdef _SC_THREAD_STACK_MIN
7485 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7486#endif
7487#ifdef _SC_THREAD_THREADS_MAX
7488 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7489#endif
7490#ifdef _SC_TIMERS
7491 {"SC_TIMERS", _SC_TIMERS},
7492#endif
7493#ifdef _SC_TIMER_MAX
7494 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7495#endif
7496#ifdef _SC_TTY_NAME_MAX
7497 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7498#endif
7499#ifdef _SC_TZNAME_MAX
7500 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7501#endif
7502#ifdef _SC_T_IOV_MAX
7503 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7504#endif
7505#ifdef _SC_UCHAR_MAX
7506 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7507#endif
7508#ifdef _SC_UINT_MAX
7509 {"SC_UINT_MAX", _SC_UINT_MAX},
7510#endif
7511#ifdef _SC_UIO_MAXIOV
7512 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7513#endif
7514#ifdef _SC_ULONG_MAX
7515 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7516#endif
7517#ifdef _SC_USHRT_MAX
7518 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7519#endif
7520#ifdef _SC_VERSION
7521 {"SC_VERSION", _SC_VERSION},
7522#endif
7523#ifdef _SC_WORD_BIT
7524 {"SC_WORD_BIT", _SC_WORD_BIT},
7525#endif
7526#ifdef _SC_XBS5_ILP32_OFF32
7527 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7528#endif
7529#ifdef _SC_XBS5_ILP32_OFFBIG
7530 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7531#endif
7532#ifdef _SC_XBS5_LP64_OFF64
7533 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7534#endif
7535#ifdef _SC_XBS5_LPBIG_OFFBIG
7536 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7537#endif
7538#ifdef _SC_XOPEN_CRYPT
7539 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7540#endif
7541#ifdef _SC_XOPEN_ENH_I18N
7542 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7543#endif
7544#ifdef _SC_XOPEN_LEGACY
7545 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7546#endif
7547#ifdef _SC_XOPEN_REALTIME
7548 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7549#endif
7550#ifdef _SC_XOPEN_REALTIME_THREADS
7551 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7552#endif
7553#ifdef _SC_XOPEN_SHM
7554 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7555#endif
7556#ifdef _SC_XOPEN_UNIX
7557 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7558#endif
7559#ifdef _SC_XOPEN_VERSION
7560 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7561#endif
7562#ifdef _SC_XOPEN_XCU_VERSION
7563 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7564#endif
7565#ifdef _SC_XOPEN_XPG2
7566 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7567#endif
7568#ifdef _SC_XOPEN_XPG3
7569 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7570#endif
7571#ifdef _SC_XOPEN_XPG4
7572 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7573#endif
7574};
7575
7576static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007577conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007578{
7579 return conv_confname(arg, valuep, posix_constants_sysconf,
7580 sizeof(posix_constants_sysconf)
7581 / sizeof(struct constdef));
7582}
7583
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007584PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007585"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007586Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007587
7588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007589posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007590{
7591 PyObject *result = NULL;
7592 int name;
7593
7594 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7595 int value;
7596
7597 errno = 0;
7598 value = sysconf(name);
7599 if (value == -1 && errno != 0)
7600 posix_error();
7601 else
7602 result = PyInt_FromLong(value);
7603 }
7604 return result;
7605}
7606#endif
7607
7608
Fred Drakebec628d1999-12-15 18:31:10 +00007609/* This code is used to ensure that the tables of configuration value names
7610 * are in sorted order as required by conv_confname(), and also to build the
7611 * the exported dictionaries that are used to publish information about the
7612 * names available on the host platform.
7613 *
7614 * Sorting the table at runtime ensures that the table is properly ordered
7615 * when used, even for platforms we're not able to test on. It also makes
7616 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007617 */
Fred Drakebec628d1999-12-15 18:31:10 +00007618
7619static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007620cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007621{
7622 const struct constdef *c1 =
7623 (const struct constdef *) v1;
7624 const struct constdef *c2 =
7625 (const struct constdef *) v2;
7626
7627 return strcmp(c1->name, c2->name);
7628}
7629
7630static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007631setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007632 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007633{
Fred Drakebec628d1999-12-15 18:31:10 +00007634 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007635 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007636
7637 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7638 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007639 if (d == NULL)
7640 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007641
Barry Warsaw3155db32000-04-13 15:20:40 +00007642 for (i=0; i < tablesize; ++i) {
7643 PyObject *o = PyInt_FromLong(table[i].value);
7644 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7645 Py_XDECREF(o);
7646 Py_DECREF(d);
7647 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007648 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007649 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007650 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007651 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007652}
7653
Fred Drakebec628d1999-12-15 18:31:10 +00007654/* Return -1 on failure, 0 on success. */
7655static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007656setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007657{
7658#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007659 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007660 sizeof(posix_constants_pathconf)
7661 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007662 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007663 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007664#endif
7665#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007666 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007667 sizeof(posix_constants_confstr)
7668 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007669 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007670 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007671#endif
7672#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007673 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007674 sizeof(posix_constants_sysconf)
7675 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007676 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007677 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007678#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007679 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007680}
Fred Draked86ed291999-12-15 15:34:33 +00007681
7682
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007683PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007684"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007685Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007686in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007687
7688static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007689posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007690{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007691 abort();
7692 /*NOTREACHED*/
7693 Py_FatalError("abort() called from Python code didn't abort!");
7694 return NULL;
7695}
Fred Drakebec628d1999-12-15 18:31:10 +00007696
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007697#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007698PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007699"startfile(filepath [, operation]) - Start a file with its associated\n\
7700application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007701\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007702When \"operation\" is not specified or \"open\", this acts like\n\
7703double-clicking the file in Explorer, or giving the file name as an\n\
7704argument to the DOS \"start\" command: the file is opened with whatever\n\
7705application (if any) its extension is associated.\n\
7706When another \"operation\" is given, it specifies what should be done with\n\
7707the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007708\n\
7709startfile returns as soon as the associated application is launched.\n\
7710There is no option to wait for the application to close, and no way\n\
7711to retrieve the application's exit status.\n\
7712\n\
7713The filepath is relative to the current directory. If you want to use\n\
7714an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007715the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007716
7717static PyObject *
7718win32_startfile(PyObject *self, PyObject *args)
7719{
7720 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007721 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007722 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007723#ifdef Py_WIN_WIDE_FILENAMES
7724 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007725 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007726 if (!PyArg_ParseTuple(args, "U|s:startfile",
7727 &unipath, &operation)) {
7728 PyErr_Clear();
7729 goto normal;
7730 }
7731
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007732
7733 if (operation) {
7734 woperation = PyUnicode_DecodeASCII(operation,
7735 strlen(operation), NULL);
7736 if (!woperation) {
7737 PyErr_Clear();
7738 operation = NULL;
7739 goto normal;
7740 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007741 }
7742
7743 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007744 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007745 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007746 NULL, NULL, SW_SHOWNORMAL);
7747 Py_END_ALLOW_THREADS
7748
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007749 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007750 if (rc <= (HINSTANCE)32) {
7751 PyObject *errval = win32_error_unicode("startfile",
7752 PyUnicode_AS_UNICODE(unipath));
7753 return errval;
7754 }
7755 Py_INCREF(Py_None);
7756 return Py_None;
7757 }
7758#endif
7759
7760normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007761 if (!PyArg_ParseTuple(args, "et|s:startfile",
7762 Py_FileSystemDefaultEncoding, &filepath,
7763 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007764 return NULL;
7765 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007766 rc = ShellExecute((HWND)0, operation, filepath,
7767 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007768 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007769 if (rc <= (HINSTANCE)32) {
7770 PyObject *errval = win32_error("startfile", filepath);
7771 PyMem_Free(filepath);
7772 return errval;
7773 }
7774 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007775 Py_INCREF(Py_None);
7776 return Py_None;
7777}
7778#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007779
Martin v. Löwis438b5342002-12-27 10:16:42 +00007780#ifdef HAVE_GETLOADAVG
7781PyDoc_STRVAR(posix_getloadavg__doc__,
7782"getloadavg() -> (float, float, float)\n\n\
7783Return the number of processes in the system run queue averaged over\n\
7784the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7785was unobtainable");
7786
7787static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007788posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007789{
7790 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007791 if (getloadavg(loadavg, 3)!=3) {
7792 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7793 return NULL;
7794 } else
7795 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7796}
7797#endif
7798
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007799#ifdef MS_WINDOWS
7800
7801PyDoc_STRVAR(win32_urandom__doc__,
7802"urandom(n) -> str\n\n\
7803Return a string of n random bytes suitable for cryptographic use.");
7804
7805typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7806 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7807 DWORD dwFlags );
7808typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7809 BYTE *pbBuffer );
7810
7811static CRYPTGENRANDOM pCryptGenRandom = NULL;
7812static HCRYPTPROV hCryptProv = 0;
7813
Tim Peters4ad82172004-08-30 17:02:04 +00007814static PyObject*
7815win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007816{
Tim Petersd3115382004-08-30 17:36:46 +00007817 int howMany;
7818 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007819
Tim Peters4ad82172004-08-30 17:02:04 +00007820 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007821 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007822 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007823 if (howMany < 0)
7824 return PyErr_Format(PyExc_ValueError,
7825 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007826
Tim Peters4ad82172004-08-30 17:02:04 +00007827 if (hCryptProv == 0) {
7828 HINSTANCE hAdvAPI32 = NULL;
7829 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007830
Tim Peters4ad82172004-08-30 17:02:04 +00007831 /* Obtain handle to the DLL containing CryptoAPI
7832 This should not fail */
7833 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7834 if(hAdvAPI32 == NULL)
7835 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007836
Tim Peters4ad82172004-08-30 17:02:04 +00007837 /* Obtain pointers to the CryptoAPI functions
7838 This will fail on some early versions of Win95 */
7839 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7840 hAdvAPI32,
7841 "CryptAcquireContextA");
7842 if (pCryptAcquireContext == NULL)
7843 return PyErr_Format(PyExc_NotImplementedError,
7844 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007845
Tim Peters4ad82172004-08-30 17:02:04 +00007846 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7847 hAdvAPI32, "CryptGenRandom");
7848 if (pCryptAcquireContext == NULL)
7849 return PyErr_Format(PyExc_NotImplementedError,
7850 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007851
Tim Peters4ad82172004-08-30 17:02:04 +00007852 /* Acquire context */
7853 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7854 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7855 return win32_error("CryptAcquireContext", NULL);
7856 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007857
Tim Peters4ad82172004-08-30 17:02:04 +00007858 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007859 result = PyString_FromStringAndSize(NULL, howMany);
7860 if (result != NULL) {
7861 /* Get random data */
7862 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7863 PyString_AS_STRING(result))) {
7864 Py_DECREF(result);
7865 return win32_error("CryptGenRandom", NULL);
7866 }
Tim Peters4ad82172004-08-30 17:02:04 +00007867 }
Tim Petersd3115382004-08-30 17:36:46 +00007868 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007869}
7870#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007871
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007872static PyMethodDef posix_methods[] = {
7873 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7874#ifdef HAVE_TTYNAME
7875 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7876#endif
7877 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7878 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007879#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007880 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007881#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007882#ifdef HAVE_LCHOWN
7883 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7884#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007885#ifdef HAVE_CHROOT
7886 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7887#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007888#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007889 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007890#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007891#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007892 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007893#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007894 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007895#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007896#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007897#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007898 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007899#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007900 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7901 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7902 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007903#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007904 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007905#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007906#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007907 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007908#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007909 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7910 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7911 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007912 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007913#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007914 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007915#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007917 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007918#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007919 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007920#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007921 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007922#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007923 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7924 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7925 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007926#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007927 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007928#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007929 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007930#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007931 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7932 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007933#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007934#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007935 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7936 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007937#if defined(PYOS_OS2)
7938 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7939 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7940#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007941#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007942#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007943 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007944#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007945#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007946 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007947#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007948#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007949 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007950#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007951#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007952 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007953#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007954#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007955 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007956#endif /* HAVE_GETEGID */
7957#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007958 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007959#endif /* HAVE_GETEUID */
7960#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007961 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007962#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007963#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007964 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007965#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007966 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007967#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007968 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007969#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007970#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007971 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007972#endif /* HAVE_GETPPID */
7973#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007974 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007975#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007976#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007977 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007978#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007979#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007980 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007981#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007982#ifdef HAVE_KILLPG
7983 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7984#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007985#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007986 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007987#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007988#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007989 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007990#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007991 {"popen2", win32_popen2, METH_VARARGS},
7992 {"popen3", win32_popen3, METH_VARARGS},
7993 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007994 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007995#else
7996#if defined(PYOS_OS2) && defined(PYCC_GCC)
7997 {"popen2", os2emx_popen2, METH_VARARGS},
7998 {"popen3", os2emx_popen3, METH_VARARGS},
7999 {"popen4", os2emx_popen4, METH_VARARGS},
8000#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008001#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008002#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008003#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008004 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008005#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00008006#ifdef HAVE_SETEUID
8007 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8008#endif /* HAVE_SETEUID */
8009#ifdef HAVE_SETEGID
8010 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8011#endif /* HAVE_SETEGID */
8012#ifdef HAVE_SETREUID
8013 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8014#endif /* HAVE_SETREUID */
8015#ifdef HAVE_SETREGID
8016 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8017#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008018#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008019 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008020#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008021#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008022 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008023#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008024#ifdef HAVE_GETPGID
8025 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8026#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008027#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008028 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008029#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008030#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008031 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008032#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008033#ifdef HAVE_WAIT3
8034 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8035#endif /* HAVE_WAIT3 */
8036#ifdef HAVE_WAIT4
8037 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8038#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008039#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008040 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008041#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008042#ifdef HAVE_GETSID
8043 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8044#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008045#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008046 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008047#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008048#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008049 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008050#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008051#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008052 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008053#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008054#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008055 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008056#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008057 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8058 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8059 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8060 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8061 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8062 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8063 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8064 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8065 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008066 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008067#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008068 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008069#endif
8070#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008071 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008072#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008073#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008074 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8075#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008076#ifdef HAVE_DEVICE_MACROS
8077 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8078 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8079 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8080#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008081#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008082 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008083#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008084#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008085 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008086#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008087#ifdef HAVE_UNSETENV
8088 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8089#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008090#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008091 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008092#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008093#ifdef HAVE_FCHDIR
8094 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8095#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008096#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008097 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008098#endif
8099#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008100 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008101#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008102#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008103#ifdef WCOREDUMP
8104 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8105#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008106#ifdef WIFCONTINUED
8107 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8108#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008109#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008110 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008111#endif /* WIFSTOPPED */
8112#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008113 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008114#endif /* WIFSIGNALED */
8115#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008116 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008117#endif /* WIFEXITED */
8118#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008119 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008120#endif /* WEXITSTATUS */
8121#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008122 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008123#endif /* WTERMSIG */
8124#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008125 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008126#endif /* WSTOPSIG */
8127#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008128#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008129 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008130#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008131#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008132 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008133#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008134#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008135 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008136#endif
8137#ifdef HAVE_TEMPNAM
8138 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8139#endif
8140#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008141 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008142#endif
Fred Drakec9680921999-12-13 16:37:25 +00008143#ifdef HAVE_CONFSTR
8144 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8145#endif
8146#ifdef HAVE_SYSCONF
8147 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8148#endif
8149#ifdef HAVE_FPATHCONF
8150 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8151#endif
8152#ifdef HAVE_PATHCONF
8153 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8154#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008155 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008156#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008157 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8158#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008159#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008160 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008161#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008162 #ifdef MS_WINDOWS
8163 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8164 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008165 {NULL, NULL} /* Sentinel */
8166};
8167
8168
Barry Warsaw4a342091996-12-19 23:50:02 +00008169static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008170ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008171{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008172 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008173}
8174
Guido van Rossumd48f2521997-12-05 22:19:34 +00008175#if defined(PYOS_OS2)
8176/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008177static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008178{
8179 APIRET rc;
8180 ULONG values[QSV_MAX+1];
8181 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008182 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008183
8184 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008185 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008186 Py_END_ALLOW_THREADS
8187
8188 if (rc != NO_ERROR) {
8189 os2_error(rc);
8190 return -1;
8191 }
8192
Fred Drake4d1e64b2002-04-15 19:40:07 +00008193 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8194 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8195 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8196 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8197 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8198 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8199 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008200
8201 switch (values[QSV_VERSION_MINOR]) {
8202 case 0: ver = "2.00"; break;
8203 case 10: ver = "2.10"; break;
8204 case 11: ver = "2.11"; break;
8205 case 30: ver = "3.00"; break;
8206 case 40: ver = "4.00"; break;
8207 case 50: ver = "5.00"; break;
8208 default:
Tim Peters885d4572001-11-28 20:27:42 +00008209 PyOS_snprintf(tmp, sizeof(tmp),
8210 "%d-%d", values[QSV_VERSION_MAJOR],
8211 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008212 ver = &tmp[0];
8213 }
8214
8215 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008216 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008217 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008218
8219 /* Add Indicator of Which Drive was Used to Boot the System */
8220 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8221 tmp[1] = ':';
8222 tmp[2] = '\0';
8223
Fred Drake4d1e64b2002-04-15 19:40:07 +00008224 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008225}
8226#endif
8227
Barry Warsaw4a342091996-12-19 23:50:02 +00008228static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008229all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008230{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008231#ifdef F_OK
8232 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008233#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008234#ifdef R_OK
8235 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008236#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008237#ifdef W_OK
8238 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008239#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008240#ifdef X_OK
8241 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008242#endif
Fred Drakec9680921999-12-13 16:37:25 +00008243#ifdef NGROUPS_MAX
8244 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8245#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008246#ifdef TMP_MAX
8247 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8248#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008249#ifdef WCONTINUED
8250 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8251#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008252#ifdef WNOHANG
8253 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008254#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008255#ifdef WUNTRACED
8256 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8257#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008258#ifdef O_RDONLY
8259 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8260#endif
8261#ifdef O_WRONLY
8262 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8263#endif
8264#ifdef O_RDWR
8265 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8266#endif
8267#ifdef O_NDELAY
8268 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8269#endif
8270#ifdef O_NONBLOCK
8271 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8272#endif
8273#ifdef O_APPEND
8274 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8275#endif
8276#ifdef O_DSYNC
8277 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8278#endif
8279#ifdef O_RSYNC
8280 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8281#endif
8282#ifdef O_SYNC
8283 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8284#endif
8285#ifdef O_NOCTTY
8286 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8287#endif
8288#ifdef O_CREAT
8289 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8290#endif
8291#ifdef O_EXCL
8292 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8293#endif
8294#ifdef O_TRUNC
8295 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8296#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008297#ifdef O_BINARY
8298 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8299#endif
8300#ifdef O_TEXT
8301 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8302#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008303#ifdef O_LARGEFILE
8304 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8305#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008306#ifdef O_SHLOCK
8307 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8308#endif
8309#ifdef O_EXLOCK
8310 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8311#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008312
Tim Peters5aa91602002-01-30 05:46:57 +00008313/* MS Windows */
8314#ifdef O_NOINHERIT
8315 /* Don't inherit in child processes. */
8316 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8317#endif
8318#ifdef _O_SHORT_LIVED
8319 /* Optimize for short life (keep in memory). */
8320 /* MS forgot to define this one with a non-underscore form too. */
8321 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8322#endif
8323#ifdef O_TEMPORARY
8324 /* Automatically delete when last handle is closed. */
8325 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8326#endif
8327#ifdef O_RANDOM
8328 /* Optimize for random access. */
8329 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8330#endif
8331#ifdef O_SEQUENTIAL
8332 /* Optimize for sequential access. */
8333 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8334#endif
8335
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008336/* GNU extensions. */
8337#ifdef O_DIRECT
8338 /* Direct disk access. */
8339 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8340#endif
8341#ifdef O_DIRECTORY
8342 /* Must be a directory. */
8343 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8344#endif
8345#ifdef O_NOFOLLOW
8346 /* Do not follow links. */
8347 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8348#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008349
Barry Warsaw5676bd12003-01-07 20:57:09 +00008350 /* These come from sysexits.h */
8351#ifdef EX_OK
8352 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008353#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008354#ifdef EX_USAGE
8355 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008356#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008357#ifdef EX_DATAERR
8358 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008359#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008360#ifdef EX_NOINPUT
8361 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008362#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008363#ifdef EX_NOUSER
8364 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008365#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008366#ifdef EX_NOHOST
8367 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008368#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008369#ifdef EX_UNAVAILABLE
8370 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008371#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008372#ifdef EX_SOFTWARE
8373 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008374#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008375#ifdef EX_OSERR
8376 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008377#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008378#ifdef EX_OSFILE
8379 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008380#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008381#ifdef EX_CANTCREAT
8382 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008383#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008384#ifdef EX_IOERR
8385 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008386#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008387#ifdef EX_TEMPFAIL
8388 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008389#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008390#ifdef EX_PROTOCOL
8391 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008392#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008393#ifdef EX_NOPERM
8394 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008395#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008396#ifdef EX_CONFIG
8397 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008398#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008399#ifdef EX_NOTFOUND
8400 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008401#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008402
Guido van Rossum246bc171999-02-01 23:54:31 +00008403#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008404#if defined(PYOS_OS2) && defined(PYCC_GCC)
8405 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8406 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8407 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8408 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8409 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8410 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8411 if (ins(d, "P_PM", (long)P_PM)) return -1;
8412 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8413 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8414 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8415 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8416 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8417 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8418 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8419 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8420 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8421 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8422 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8423 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8424 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8425#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008426 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8427 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8428 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8429 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8430 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008431#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008432#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008433
Guido van Rossumd48f2521997-12-05 22:19:34 +00008434#if defined(PYOS_OS2)
8435 if (insertvalues(d)) return -1;
8436#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008437 return 0;
8438}
8439
8440
Tim Peters5aa91602002-01-30 05:46:57 +00008441#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008442#define INITFUNC initnt
8443#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008444
8445#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008446#define INITFUNC initos2
8447#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008448
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008449#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008450#define INITFUNC initposix
8451#define MODNAME "posix"
8452#endif
8453
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008454PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008455INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008456{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008457 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008458
Fred Drake4d1e64b2002-04-15 19:40:07 +00008459 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008460 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008461 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008462 if (m == NULL)
8463 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008464
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008465 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008466 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008467 Py_XINCREF(v);
8468 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008469 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008470 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008471
Fred Drake4d1e64b2002-04-15 19:40:07 +00008472 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008473 return;
8474
Fred Drake4d1e64b2002-04-15 19:40:07 +00008475 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008476 return;
8477
Fred Drake4d1e64b2002-04-15 19:40:07 +00008478 Py_INCREF(PyExc_OSError);
8479 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008480
Guido van Rossumb3d39562000-01-31 18:41:26 +00008481#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008482 if (posix_putenv_garbage == NULL)
8483 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008484#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008485
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008486 if (!initialized) {
8487 stat_result_desc.name = MODNAME ".stat_result";
8488 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8489 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8490 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8491 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8492 structseq_new = StatResultType.tp_new;
8493 StatResultType.tp_new = statresult_new;
8494
8495 statvfs_result_desc.name = MODNAME ".statvfs_result";
8496 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8497 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008498 Py_INCREF((PyObject*) &StatResultType);
8499 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008500 Py_INCREF((PyObject*) &StatVFSResultType);
8501 PyModule_AddObject(m, "statvfs_result",
8502 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008503 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008504
8505#ifdef __APPLE__
8506 /*
8507 * Step 2 of weak-linking support on Mac OS X.
8508 *
8509 * The code below removes functions that are not available on the
8510 * currently active platform.
8511 *
8512 * This block allow one to use a python binary that was build on
8513 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8514 * OSX 10.4.
8515 */
8516#ifdef HAVE_FSTATVFS
8517 if (fstatvfs == NULL) {
8518 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8519 return;
8520 }
8521 }
8522#endif /* HAVE_FSTATVFS */
8523
8524#ifdef HAVE_STATVFS
8525 if (statvfs == NULL) {
8526 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8527 return;
8528 }
8529 }
8530#endif /* HAVE_STATVFS */
8531
8532# ifdef HAVE_LCHOWN
8533 if (lchown == NULL) {
8534 if (PyObject_DelAttrString(m, "lchown") == -1) {
8535 return;
8536 }
8537 }
8538#endif /* HAVE_LCHOWN */
8539
8540
8541#endif /* __APPLE__ */
8542
Guido van Rossumb6775db1994-08-01 11:34:53 +00008543}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008544
8545#ifdef __cplusplus
8546}
8547#endif
8548