blob: bce73a6f569df1aaa03849dbe0b6abf08a3742ac [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{
766 /* XXX endianness */
767 __int64 in = *(__int64*)in_ptr;
768 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
769 /* XXX Win32 supports time stamps past 2038; we currently don't */
770 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
771}
772
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000773static void
774time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
775{
776 /* XXX endianness */
777 __int64 out;
778 out = time_in + secs_between_epochs;
779 out = out * 10000000 + nsec_in;
780 *(__int64*)out_ptr = out;
781}
782
Martin v. Löwis14694662006-02-03 12:54:16 +0000783/* Below, we *know* that ugo+r is 0444 */
784#if _S_IREAD != 0400
785#error Unsupported C library
786#endif
787static int
788attributes_to_mode(DWORD attr)
789{
790 int m = 0;
791 if (attr & FILE_ATTRIBUTE_DIRECTORY)
792 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
793 else
794 m |= _S_IFREG;
795 if (attr & FILE_ATTRIBUTE_READONLY)
796 m |= 0444;
797 else
798 m |= 0666;
799 return m;
800}
801
802static int
803attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
804{
805 memset(result, 0, sizeof(*result));
806 result->st_mode = attributes_to_mode(info->dwFileAttributes);
807 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
808 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
809 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
810 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
811
812 return 0;
813}
814
815static int
816win32_stat(const char* path, struct win32_stat *result)
817{
818 WIN32_FILE_ATTRIBUTE_DATA info;
819 int code;
820 char *dot;
821 /* XXX not supported on Win95 and NT 3.x */
822 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
823 /* Protocol violation: we explicitly clear errno, instead of
824 setting it to a POSIX error. Callers should use GetLastError. */
825 errno = 0;
826 return -1;
827 }
828 code = attribute_data_to_stat(&info, result);
829 if (code != 0)
830 return code;
831 /* Set S_IFEXEC if it is an .exe, .bat, ... */
832 dot = strrchr(path, '.');
833 if (dot) {
834 if (stricmp(dot, ".bat") == 0 ||
835 stricmp(dot, ".cmd") == 0 ||
836 stricmp(dot, ".exe") == 0 ||
837 stricmp(dot, ".com") == 0)
838 result->st_mode |= 0111;
839 }
840 return code;
841}
842
843static int
844win32_wstat(const wchar_t* path, struct win32_stat *result)
845{
846 int code;
847 const wchar_t *dot;
848 WIN32_FILE_ATTRIBUTE_DATA info;
849 /* XXX not supported on Win95 and NT 3.x */
850 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
851 /* Protocol violation: we explicitly clear errno, instead of
852 setting it to a POSIX error. Callers should use GetLastError. */
853 errno = 0;
854 return -1;
855 }
856 code = attribute_data_to_stat(&info, result);
857 if (code < 0)
858 return code;
859 /* Set IFEXEC if it is an .exe, .bat, ... */
860 dot = wcsrchr(path, '.');
861 if (dot) {
862 if (_wcsicmp(dot, L".bat") == 0 ||
863 _wcsicmp(dot, L".cmd") == 0 ||
864 _wcsicmp(dot, L".exe") == 0 ||
865 _wcsicmp(dot, L".com") == 0)
866 result->st_mode |= 0111;
867 }
868 return code;
869}
870
871static int
872win32_fstat(int file_number, struct win32_stat *result)
873{
874 BY_HANDLE_FILE_INFORMATION info;
875 HANDLE h;
876 int type;
877
878 h = (HANDLE)_get_osfhandle(file_number);
879
880 /* Protocol violation: we explicitly clear errno, instead of
881 setting it to a POSIX error. Callers should use GetLastError. */
882 errno = 0;
883
884 if (h == INVALID_HANDLE_VALUE) {
885 /* This is really a C library error (invalid file handle).
886 We set the Win32 error to the closes one matching. */
887 SetLastError(ERROR_INVALID_HANDLE);
888 return -1;
889 }
890 memset(result, 0, sizeof(*result));
891
892 type = GetFileType(h);
893 if (type == FILE_TYPE_UNKNOWN) {
894 DWORD error = GetLastError();
895 if (error != 0) {
896 return -1;
897 }
898 /* else: valid but unknown file */
899 }
900
901 if (type != FILE_TYPE_DISK) {
902 if (type == FILE_TYPE_CHAR)
903 result->st_mode = _S_IFCHR;
904 else if (type == FILE_TYPE_PIPE)
905 result->st_mode = _S_IFIFO;
906 return 0;
907 }
908
909 if (!GetFileInformationByHandle(h, &info)) {
910 return -1;
911 }
912
913 /* similar to stat() */
914 result->st_mode = attributes_to_mode(info.dwFileAttributes);
915 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
916 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
917 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
918 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
919 /* specific to fstat() */
920 result->st_nlink = info.nNumberOfLinks;
921 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
922 return 0;
923}
924
925#endif /* MS_WINDOWS */
926
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000927PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000928"stat_result: Result from stat or lstat.\n\n\
929This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000930 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
932\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000933Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
934or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000935\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000936See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000937
938static PyStructSequence_Field stat_result_fields[] = {
939 {"st_mode", "protection bits"},
940 {"st_ino", "inode"},
941 {"st_dev", "device"},
942 {"st_nlink", "number of hard links"},
943 {"st_uid", "user ID of owner"},
944 {"st_gid", "group ID of owner"},
945 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000946 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
947 {NULL, "integer time of last access"},
948 {NULL, "integer time of last modification"},
949 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950 {"st_atime", "time of last access"},
951 {"st_mtime", "time of last modification"},
952 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000953#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000954 {"st_blksize", "blocksize for filesystem I/O"},
955#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000956#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000957 {"st_blocks", "number of blocks allocated"},
958#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000959#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000960 {"st_rdev", "device type (if inode device)"},
961#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000962#ifdef HAVE_STRUCT_STAT_ST_FLAGS
963 {"st_flags", "user defined flags for file"},
964#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000965#ifdef HAVE_STRUCT_STAT_ST_GEN
966 {"st_gen", "generation number"},
967#endif
968#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
969 {"st_birthtime", "time of creation"},
970#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000971 {0}
972};
973
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000974#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000975#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000976#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000977#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000978#endif
979
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000980#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000981#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
982#else
983#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
984#endif
985
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000986#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000987#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
988#else
989#define ST_RDEV_IDX ST_BLOCKS_IDX
990#endif
991
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000992#ifdef HAVE_STRUCT_STAT_ST_FLAGS
993#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
994#else
995#define ST_FLAGS_IDX ST_RDEV_IDX
996#endif
997
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000998#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000999#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001000#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001001#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001002#endif
1003
1004#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1005#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1006#else
1007#define ST_BIRTHTIME_IDX ST_GEN_IDX
1008#endif
1009
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001010static PyStructSequence_Desc stat_result_desc = {
1011 "stat_result", /* name */
1012 stat_result__doc__, /* doc */
1013 stat_result_fields,
1014 10
1015};
1016
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001017PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001018"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1019This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001020 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001021or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001022\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001023See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001024
1025static PyStructSequence_Field statvfs_result_fields[] = {
1026 {"f_bsize", },
1027 {"f_frsize", },
1028 {"f_blocks", },
1029 {"f_bfree", },
1030 {"f_bavail", },
1031 {"f_files", },
1032 {"f_ffree", },
1033 {"f_favail", },
1034 {"f_flag", },
1035 {"f_namemax",},
1036 {0}
1037};
1038
1039static PyStructSequence_Desc statvfs_result_desc = {
1040 "statvfs_result", /* name */
1041 statvfs_result__doc__, /* doc */
1042 statvfs_result_fields,
1043 10
1044};
1045
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001046static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001047static PyTypeObject StatResultType;
1048static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001049static newfunc structseq_new;
1050
1051static PyObject *
1052statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1053{
1054 PyStructSequence *result;
1055 int i;
1056
1057 result = (PyStructSequence*)structseq_new(type, args, kwds);
1058 if (!result)
1059 return NULL;
1060 /* If we have been initialized from a tuple,
1061 st_?time might be set to None. Initialize it
1062 from the int slots. */
1063 for (i = 7; i <= 9; i++) {
1064 if (result->ob_item[i+3] == Py_None) {
1065 Py_DECREF(Py_None);
1066 Py_INCREF(result->ob_item[i]);
1067 result->ob_item[i+3] = result->ob_item[i];
1068 }
1069 }
1070 return (PyObject*)result;
1071}
1072
1073
1074
1075/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001076static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001077
1078PyDoc_STRVAR(stat_float_times__doc__,
1079"stat_float_times([newval]) -> oldval\n\n\
1080Determine whether os.[lf]stat represents time stamps as float objects.\n\
1081If newval is True, future calls to stat() return floats, if it is False,\n\
1082future calls return ints. \n\
1083If newval is omitted, return the current setting.\n");
1084
1085static PyObject*
1086stat_float_times(PyObject* self, PyObject *args)
1087{
1088 int newval = -1;
1089 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1090 return NULL;
1091 if (newval == -1)
1092 /* Return old value */
1093 return PyBool_FromLong(_stat_float_times);
1094 _stat_float_times = newval;
1095 Py_INCREF(Py_None);
1096 return Py_None;
1097}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001099static void
1100fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1101{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001102 PyObject *fval,*ival;
1103#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001104 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001105#else
1106 ival = PyInt_FromLong((long)sec);
1107#endif
1108 if (_stat_float_times) {
1109 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1110 } else {
1111 fval = ival;
1112 Py_INCREF(fval);
1113 }
1114 PyStructSequence_SET_ITEM(v, index, ival);
1115 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001116}
1117
Tim Peters5aa91602002-01-30 05:46:57 +00001118/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001119 (used by posix_stat() and posix_fstat()) */
1120static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001121_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001122{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001123 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001125 if (v == NULL)
1126 return NULL;
1127
Martin v. Löwis14694662006-02-03 12:54:16 +00001128 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001129#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001130 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001131 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001132#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001133 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001134#endif
1135#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001136 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001137 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001138#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001139 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001140#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001141 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1142 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1143 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001144#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001145 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001146 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001147#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001148 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001149#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001150
Martin v. Löwis14694662006-02-03 12:54:16 +00001151#if defined(HAVE_STAT_TV_NSEC)
1152 ansec = st->st_atim.tv_nsec;
1153 mnsec = st->st_mtim.tv_nsec;
1154 cnsec = st->st_ctim.tv_nsec;
1155#elif defined(HAVE_STAT_TV_NSEC2)
1156 ansec = st->st_atimespec.tv_nsec;
1157 mnsec = st->st_mtimespec.tv_nsec;
1158 cnsec = st->st_ctimespec.tv_nsec;
1159#elif defined(HAVE_STAT_NSEC)
1160 ansec = st->st_atime_nsec;
1161 mnsec = st->st_mtime_nsec;
1162 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001163#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001164 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001165#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001166 fill_time(v, 7, st->st_atime, ansec);
1167 fill_time(v, 8, st->st_mtime, mnsec);
1168 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001169
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001170#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001171 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001172 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001173#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001174#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001175 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001176 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001177#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001178#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001179 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001180 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001181#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001182#ifdef HAVE_STRUCT_STAT_ST_GEN
1183 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001184 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001185#endif
1186#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1187 {
1188 PyObject *val;
1189 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001190 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001191#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001192 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001193#else
1194 bnsec = 0;
1195#endif
1196 if (_stat_float_times) {
1197 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1198 } else {
1199 val = PyInt_FromLong((long)bsec);
1200 }
1201 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1202 val);
1203 }
1204#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001205#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1206 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001207 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001208#endif
Fred Drake699f3522000-06-29 21:12:41 +00001209
1210 if (PyErr_Occurred()) {
1211 Py_DECREF(v);
1212 return NULL;
1213 }
1214
1215 return v;
1216}
1217
Martin v. Löwisd8948722004-06-02 09:57:56 +00001218#ifdef MS_WINDOWS
1219
1220/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1221 where / can be used in place of \ and the trailing slash is optional.
1222 Both SERVER and SHARE must have at least one character.
1223*/
1224
1225#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1226#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1227#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1228
Tim Peters4ad82172004-08-30 17:02:04 +00001229static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001230IsUNCRootA(char *path, int pathlen)
1231{
1232 #define ISSLASH ISSLASHA
1233
1234 int i, share;
1235
1236 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1237 /* minimum UNCRoot is \\x\y */
1238 return FALSE;
1239 for (i = 2; i < pathlen ; i++)
1240 if (ISSLASH(path[i])) break;
1241 if (i == 2 || i == pathlen)
1242 /* do not allow \\\SHARE or \\SERVER */
1243 return FALSE;
1244 share = i+1;
1245 for (i = share; i < pathlen; i++)
1246 if (ISSLASH(path[i])) break;
1247 return (i != share && (i == pathlen || i == pathlen-1));
1248
1249 #undef ISSLASH
1250}
1251
1252#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001253static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001254IsUNCRootW(Py_UNICODE *path, int pathlen)
1255{
1256 #define ISSLASH ISSLASHW
1257
1258 int i, share;
1259
1260 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1261 /* minimum UNCRoot is \\x\y */
1262 return FALSE;
1263 for (i = 2; i < pathlen ; i++)
1264 if (ISSLASH(path[i])) break;
1265 if (i == 2 || i == pathlen)
1266 /* do not allow \\\SHARE or \\SERVER */
1267 return FALSE;
1268 share = i+1;
1269 for (i = share; i < pathlen; i++)
1270 if (ISSLASH(path[i])) break;
1271 return (i != share && (i == pathlen || i == pathlen-1));
1272
1273 #undef ISSLASH
1274}
1275#endif /* Py_WIN_WIDE_FILENAMES */
1276#endif /* MS_WINDOWS */
1277
Barry Warsaw53699e91996-12-10 23:23:01 +00001278static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001279posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001280 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001281#ifdef __VMS
1282 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1283#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001284 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001285#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001286 char *wformat,
1287 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288{
Fred Drake699f3522000-06-29 21:12:41 +00001289 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001290 char *path = NULL; /* pass this to stat; do not free() it */
1291 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001292 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001293 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001294
1295#ifdef Py_WIN_WIDE_FILENAMES
1296 /* If on wide-character-capable OS see if argument
1297 is Unicode and if so use wide API. */
1298 if (unicode_file_names()) {
1299 PyUnicodeObject *po;
1300 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001301 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1302
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001303 Py_BEGIN_ALLOW_THREADS
1304 /* PyUnicode_AS_UNICODE result OK without
1305 thread lock as it is a simple dereference. */
1306 res = wstatfunc(wpath, &st);
1307 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001308
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001309 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001310 return win32_error_unicode("stat", wpath);
1311 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001312 }
1313 /* Drop the argument parsing error as narrow strings
1314 are also valid. */
1315 PyErr_Clear();
1316 }
1317#endif
1318
Tim Peters5aa91602002-01-30 05:46:57 +00001319 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001320 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001321 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001322 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001325 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001326 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001327
1328 if (res != 0) {
1329#ifdef MS_WINDOWS
1330 result = win32_error("stat", pathfree);
1331#else
1332 result = posix_error_with_filename(pathfree);
1333#endif
1334 }
1335 else
1336 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001337
Tim Peters500bd032001-12-19 19:05:01 +00001338 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001339 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340}
1341
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342/* POSIX methods */
1343
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001344PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001345"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001346Use the real uid/gid to test for access to a path. Note that most\n\
1347operations will use the effective uid/gid, therefore this routine can\n\
1348be used in a suid/sgid environment to test if the invoking user has the\n\
1349specified access to the path. The mode argument can be F_OK to test\n\
1350existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001351
1352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001353posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001354{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001355 char *path;
1356 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001357
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001358#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001359 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001360 if (unicode_file_names()) {
1361 PyUnicodeObject *po;
1362 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1363 Py_BEGIN_ALLOW_THREADS
1364 /* PyUnicode_AS_UNICODE OK without thread lock as
1365 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001366 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001367 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001368 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001369 }
1370 /* Drop the argument parsing error as narrow strings
1371 are also valid. */
1372 PyErr_Clear();
1373 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001374 if (!PyArg_ParseTuple(args, "eti:access",
1375 Py_FileSystemDefaultEncoding, &path, &mode))
1376 return 0;
1377 Py_BEGIN_ALLOW_THREADS
1378 attr = GetFileAttributesA(path);
1379 Py_END_ALLOW_THREADS
1380 PyMem_Free(path);
1381finish:
1382 if (attr == 0xFFFFFFFF)
1383 /* File does not exist, or cannot read attributes */
1384 return PyBool_FromLong(0);
1385 /* Access is possible if either write access wasn't requested, or
1386 the file isn't read-only. */
1387 return PyBool_FromLong(!(mode & 2) || !(attr && FILE_ATTRIBUTE_READONLY));
1388#else
1389 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001390 if (!PyArg_ParseTuple(args, "eti:access",
1391 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001392 return NULL;
1393 Py_BEGIN_ALLOW_THREADS
1394 res = access(path, mode);
1395 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001396 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001397 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001398#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001399}
1400
Guido van Rossumd371ff11999-01-25 16:12:23 +00001401#ifndef F_OK
1402#define F_OK 0
1403#endif
1404#ifndef R_OK
1405#define R_OK 4
1406#endif
1407#ifndef W_OK
1408#define W_OK 2
1409#endif
1410#ifndef X_OK
1411#define X_OK 1
1412#endif
1413
1414#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001415PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001416"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001417Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001418
1419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001420posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001421{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001422 int id;
1423 char *ret;
1424
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001425 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001426 return NULL;
1427
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001428#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001429 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001430 if (id == 0) {
1431 ret = ttyname();
1432 }
1433 else {
1434 ret = NULL;
1435 }
1436#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001437 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001438#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001439 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001440 return posix_error();
1441 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001442}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001443#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001444
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001445#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001446PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001447"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001448Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001449
1450static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001451posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001452{
1453 char *ret;
1454 char buffer[L_ctermid];
1455
Greg Wardb48bc172000-03-01 21:51:56 +00001456#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001457 ret = ctermid_r(buffer);
1458#else
1459 ret = ctermid(buffer);
1460#endif
1461 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001462 return posix_error();
1463 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001464}
1465#endif
1466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001467PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001468"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001469Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001470
Barry Warsaw53699e91996-12-10 23:23:01 +00001471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001472posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001473{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001474#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001475 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001476#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001477 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001478#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001479 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001480#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001481 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001482#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001483}
1484
Fred Drake4d1e64b2002-04-15 19:40:07 +00001485#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001486PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001487"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001488Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001490
1491static PyObject *
1492posix_fchdir(PyObject *self, PyObject *fdobj)
1493{
1494 return posix_fildes(fdobj, fchdir);
1495}
1496#endif /* HAVE_FCHDIR */
1497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001499PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001500"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001501Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001502
Barry Warsaw53699e91996-12-10 23:23:01 +00001503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001504posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001505{
Mark Hammondef8b6542001-05-13 08:04:26 +00001506 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001507 int i;
1508 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001509#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001510 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001511 if (unicode_file_names()) {
1512 PyUnicodeObject *po;
1513 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1514 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001515 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1516 if (attr != 0xFFFFFFFF) {
1517 if (i & _S_IWRITE)
1518 attr &= ~FILE_ATTRIBUTE_READONLY;
1519 else
1520 attr |= FILE_ATTRIBUTE_READONLY;
1521 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1522 }
1523 else
1524 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001525 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001526 if (!res)
1527 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001528 PyUnicode_AS_UNICODE(po));
1529 Py_INCREF(Py_None);
1530 return Py_None;
1531 }
1532 /* Drop the argument parsing error as narrow strings
1533 are also valid. */
1534 PyErr_Clear();
1535 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001536 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1537 &path, &i))
1538 return NULL;
1539 Py_BEGIN_ALLOW_THREADS
1540 attr = GetFileAttributesA(path);
1541 if (attr != 0xFFFFFFFF) {
1542 if (i & _S_IWRITE)
1543 attr &= ~FILE_ATTRIBUTE_READONLY;
1544 else
1545 attr |= FILE_ATTRIBUTE_READONLY;
1546 res = SetFileAttributesA(path, attr);
1547 }
1548 else
1549 res = 0;
1550 Py_END_ALLOW_THREADS
1551 if (!res) {
1552 win32_error("chmod", path);
1553 PyMem_Free(path);
1554 return NULL;
1555 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001556 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001557 Py_INCREF(Py_None);
1558 return Py_None;
1559#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001560 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001561 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001562 return NULL;
1563 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001564 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001565 Py_END_ALLOW_THREADS
1566 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001567 return posix_error_with_allocated_filename(path);
1568 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001569 Py_INCREF(Py_None);
1570 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001571#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001572}
1573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001574
Martin v. Löwis244edc82001-10-04 22:44:26 +00001575#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001576PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001577"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001578Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001579
1580static PyObject *
1581posix_chroot(PyObject *self, PyObject *args)
1582{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001583 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001584}
1585#endif
1586
Guido van Rossum21142a01999-01-08 21:05:37 +00001587#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001588PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001589"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001590force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001591
1592static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001593posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001594{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001595 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001596}
1597#endif /* HAVE_FSYNC */
1598
1599#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001600
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001601#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001602extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1603#endif
1604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001605PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001606"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001607force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001609
1610static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001611posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001612{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001613 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001614}
1615#endif /* HAVE_FDATASYNC */
1616
1617
Fredrik Lundh10723342000-07-10 16:38:09 +00001618#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001619PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001620"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001621Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001624posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001625{
Mark Hammondef8b6542001-05-13 08:04:26 +00001626 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001627 int uid, gid;
1628 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001629 if (!PyArg_ParseTuple(args, "etii:chown",
1630 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001631 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001632 return NULL;
1633 Py_BEGIN_ALLOW_THREADS
1634 res = chown(path, (uid_t) uid, (gid_t) gid);
1635 Py_END_ALLOW_THREADS
1636 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001637 return posix_error_with_allocated_filename(path);
1638 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001639 Py_INCREF(Py_None);
1640 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001641}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001642#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001643
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001644#ifdef HAVE_LCHOWN
1645PyDoc_STRVAR(posix_lchown__doc__,
1646"lchown(path, uid, gid)\n\n\
1647Change the owner and group id of path to the numeric uid and gid.\n\
1648This function will not follow symbolic links.");
1649
1650static PyObject *
1651posix_lchown(PyObject *self, PyObject *args)
1652{
1653 char *path = NULL;
1654 int uid, gid;
1655 int res;
1656 if (!PyArg_ParseTuple(args, "etii:lchown",
1657 Py_FileSystemDefaultEncoding, &path,
1658 &uid, &gid))
1659 return NULL;
1660 Py_BEGIN_ALLOW_THREADS
1661 res = lchown(path, (uid_t) uid, (gid_t) gid);
1662 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001663 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001664 return posix_error_with_allocated_filename(path);
1665 PyMem_Free(path);
1666 Py_INCREF(Py_None);
1667 return Py_None;
1668}
1669#endif /* HAVE_LCHOWN */
1670
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001671
Guido van Rossum36bc6801995-06-14 22:54:23 +00001672#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001673PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001674"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001676
Barry Warsaw53699e91996-12-10 23:23:01 +00001677static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001678posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001679{
1680 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001681 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001682
Barry Warsaw53699e91996-12-10 23:23:01 +00001683 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001684#if defined(PYOS_OS2) && defined(PYCC_GCC)
1685 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001686#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001687 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001688#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001689 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001690 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001692 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001694
Walter Dörwald3b918c32002-11-21 20:18:46 +00001695#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001696PyDoc_STRVAR(posix_getcwdu__doc__,
1697"getcwdu() -> path\n\n\
1698Return a unicode string representing the current working directory.");
1699
1700static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001701posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001702{
1703 char buf[1026];
1704 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001705
1706#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001707 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001708 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001709 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001710 wchar_t *wbuf2 = wbuf;
1711 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001712 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001713 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1714 /* If the buffer is large enough, len does not include the
1715 terminating \0. If the buffer is too small, len includes
1716 the space needed for the terminator. */
1717 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1718 wbuf2 = malloc(len * sizeof(wchar_t));
1719 if (wbuf2)
1720 len = GetCurrentDirectoryW(len, wbuf2);
1721 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001722 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001723 if (!wbuf2) {
1724 PyErr_NoMemory();
1725 return NULL;
1726 }
1727 if (!len) {
1728 if (wbuf2 != wbuf) free(wbuf2);
1729 return win32_error("getcwdu", NULL);
1730 }
1731 resobj = PyUnicode_FromWideChar(wbuf2, len);
1732 if (wbuf2 != wbuf) free(wbuf2);
1733 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001734 }
1735#endif
1736
1737 Py_BEGIN_ALLOW_THREADS
1738#if defined(PYOS_OS2) && defined(PYCC_GCC)
1739 res = _getcwd2(buf, sizeof buf);
1740#else
1741 res = getcwd(buf, sizeof buf);
1742#endif
1743 Py_END_ALLOW_THREADS
1744 if (res == NULL)
1745 return posix_error();
1746 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1747}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001748#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001749#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001751
Guido van Rossumb6775db1994-08-01 11:34:53 +00001752#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001753PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001754"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001755Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001756
Barry Warsaw53699e91996-12-10 23:23:01 +00001757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001758posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001759{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00001760 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001761}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001762#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767Return a list containing the names of the entries in the directory.\n\
1768\n\
1769 path: path of directory to list\n\
1770\n\
1771The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001772entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001773
Barry Warsaw53699e91996-12-10 23:23:01 +00001774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001775posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001776{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001777 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001778 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001779#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001780
Barry Warsaw53699e91996-12-10 23:23:01 +00001781 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001782 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001783 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001784 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001785 /* MAX_PATH characters could mean a bigger encoded string */
1786 char namebuf[MAX_PATH*2+5];
1787 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001788 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001789
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001790#ifdef Py_WIN_WIDE_FILENAMES
1791 /* If on wide-character-capable OS see if argument
1792 is Unicode and if so use wide API. */
1793 if (unicode_file_names()) {
1794 PyUnicodeObject *po;
1795 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1796 WIN32_FIND_DATAW wFileData;
1797 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1798 Py_UNICODE wch;
1799 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1800 wnamebuf[MAX_PATH] = L'\0';
1801 len = wcslen(wnamebuf);
1802 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1803 if (wch != L'/' && wch != L'\\' && wch != L':')
1804 wnamebuf[len++] = L'/';
1805 wcscpy(wnamebuf + len, L"*.*");
1806 if ((d = PyList_New(0)) == NULL)
1807 return NULL;
1808 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1809 if (hFindFile == INVALID_HANDLE_VALUE) {
1810 errno = GetLastError();
1811 if (errno == ERROR_FILE_NOT_FOUND) {
1812 return d;
1813 }
1814 Py_DECREF(d);
1815 return win32_error_unicode("FindFirstFileW", wnamebuf);
1816 }
1817 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001818 /* Skip over . and .. */
1819 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1820 wcscmp(wFileData.cFileName, L"..") != 0) {
1821 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1822 if (v == NULL) {
1823 Py_DECREF(d);
1824 d = NULL;
1825 break;
1826 }
1827 if (PyList_Append(d, v) != 0) {
1828 Py_DECREF(v);
1829 Py_DECREF(d);
1830 d = NULL;
1831 break;
1832 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001833 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001834 }
Georg Brandl622927b2006-03-07 12:48:03 +00001835 Py_BEGIN_ALLOW_THREADS
1836 result = FindNextFileW(hFindFile, &wFileData);
1837 Py_END_ALLOW_THREADS
1838 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001839
1840 if (FindClose(hFindFile) == FALSE) {
1841 Py_DECREF(d);
1842 return win32_error_unicode("FindClose", wnamebuf);
1843 }
1844 return d;
1845 }
1846 /* Drop the argument parsing error as narrow strings
1847 are also valid. */
1848 PyErr_Clear();
1849 }
1850#endif
1851
Tim Peters5aa91602002-01-30 05:46:57 +00001852 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001853 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001855 if (len > 0) {
1856 char ch = namebuf[len-1];
1857 if (ch != SEP && ch != ALTSEP && ch != ':')
1858 namebuf[len++] = '/';
1859 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001860 strcpy(namebuf + len, "*.*");
1861
Barry Warsaw53699e91996-12-10 23:23:01 +00001862 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001863 return NULL;
1864
1865 hFindFile = FindFirstFile(namebuf, &FileData);
1866 if (hFindFile == INVALID_HANDLE_VALUE) {
1867 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001868 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001869 return d;
1870 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001871 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001872 }
1873 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001874 /* Skip over . and .. */
1875 if (strcmp(FileData.cFileName, ".") != 0 &&
1876 strcmp(FileData.cFileName, "..") != 0) {
1877 v = PyString_FromString(FileData.cFileName);
1878 if (v == NULL) {
1879 Py_DECREF(d);
1880 d = NULL;
1881 break;
1882 }
1883 if (PyList_Append(d, v) != 0) {
1884 Py_DECREF(v);
1885 Py_DECREF(d);
1886 d = NULL;
1887 break;
1888 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001889 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001890 }
Georg Brandl622927b2006-03-07 12:48:03 +00001891 Py_BEGIN_ALLOW_THREADS
1892 result = FindNextFile(hFindFile, &FileData);
1893 Py_END_ALLOW_THREADS
1894 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001895
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001896 if (FindClose(hFindFile) == FALSE) {
1897 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001898 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001899 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001900
1901 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001902
Tim Peters0bb44a42000-09-15 07:44:49 +00001903#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001904
1905#ifndef MAX_PATH
1906#define MAX_PATH CCHMAXPATH
1907#endif
1908 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001909 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001910 PyObject *d, *v;
1911 char namebuf[MAX_PATH+5];
1912 HDIR hdir = 1;
1913 ULONG srchcnt = 1;
1914 FILEFINDBUF3 ep;
1915 APIRET rc;
1916
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001917 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001918 return NULL;
1919 if (len >= MAX_PATH) {
1920 PyErr_SetString(PyExc_ValueError, "path too long");
1921 return NULL;
1922 }
1923 strcpy(namebuf, name);
1924 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001925 if (*pt == ALTSEP)
1926 *pt = SEP;
1927 if (namebuf[len-1] != SEP)
1928 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001929 strcpy(namebuf + len, "*.*");
1930
1931 if ((d = PyList_New(0)) == NULL)
1932 return NULL;
1933
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001934 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1935 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001936 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001937 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1938 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1939 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001940
1941 if (rc != NO_ERROR) {
1942 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001943 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001944 }
1945
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001946 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001947 do {
1948 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001949 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001950 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001951
1952 strcpy(namebuf, ep.achName);
1953
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001954 /* Leave Case of Name Alone -- In Native Form */
1955 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001956
1957 v = PyString_FromString(namebuf);
1958 if (v == NULL) {
1959 Py_DECREF(d);
1960 d = NULL;
1961 break;
1962 }
1963 if (PyList_Append(d, v) != 0) {
1964 Py_DECREF(v);
1965 Py_DECREF(d);
1966 d = NULL;
1967 break;
1968 }
1969 Py_DECREF(v);
1970 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1971 }
1972
1973 return d;
1974#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001975
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001976 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001978 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001979 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001980 int arg_is_unicode = 1;
1981
Georg Brandl05e89b82006-04-11 07:04:06 +00001982 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00001983 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1984 arg_is_unicode = 0;
1985 PyErr_Clear();
1986 }
1987 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001988 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001989 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001990 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001991 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001992 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001993 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001994 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001995 return NULL;
1996 }
Georg Brandl622927b2006-03-07 12:48:03 +00001997 for (;;) {
1998 Py_BEGIN_ALLOW_THREADS
1999 ep = readdir(dirp);
2000 Py_END_ALLOW_THREADS
2001 if (ep == NULL)
2002 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002003 if (ep->d_name[0] == '.' &&
2004 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002005 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002006 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002008 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002009 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002010 d = NULL;
2011 break;
2012 }
Just van Rossum46c97842003-02-25 21:42:15 +00002013#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002014 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002015 PyObject *w;
2016
2017 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002018 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002019 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002020 if (w != NULL) {
2021 Py_DECREF(v);
2022 v = w;
2023 }
2024 else {
2025 /* fall back to the original byte string, as
2026 discussed in patch #683592 */
2027 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002028 }
Just van Rossum46c97842003-02-25 21:42:15 +00002029 }
2030#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002031 if (PyList_Append(d, v) != 0) {
2032 Py_DECREF(v);
2033 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034 d = NULL;
2035 break;
2036 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002037 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002038 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00002039 if (errno != 0 && d != NULL) {
2040 /* readdir() returned NULL and set errno */
2041 closedir(dirp);
2042 Py_DECREF(d);
2043 return posix_error_with_allocated_filename(name);
2044 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002045 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002046 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002047
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002048 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002049
Tim Peters0bb44a42000-09-15 07:44:49 +00002050#endif /* which OS */
2051} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002052
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002053#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002054/* A helper function for abspath on win32 */
2055static PyObject *
2056posix__getfullpathname(PyObject *self, PyObject *args)
2057{
2058 /* assume encoded strings wont more than double no of chars */
2059 char inbuf[MAX_PATH*2];
2060 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002061 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002062 char outbuf[MAX_PATH*2];
2063 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002064#ifdef Py_WIN_WIDE_FILENAMES
2065 if (unicode_file_names()) {
2066 PyUnicodeObject *po;
2067 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2068 Py_UNICODE woutbuf[MAX_PATH*2];
2069 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002070 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002071 sizeof(woutbuf)/sizeof(woutbuf[0]),
2072 woutbuf, &wtemp))
2073 return win32_error("GetFullPathName", "");
2074 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2075 }
2076 /* Drop the argument parsing error as narrow strings
2077 are also valid. */
2078 PyErr_Clear();
2079 }
2080#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002081 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2082 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002083 &insize))
2084 return NULL;
2085 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2086 outbuf, &temp))
2087 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002088 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2089 return PyUnicode_Decode(outbuf, strlen(outbuf),
2090 Py_FileSystemDefaultEncoding, NULL);
2091 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002092 return PyString_FromString(outbuf);
2093} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002094#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002096PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002097"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002098Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002099
Barry Warsaw53699e91996-12-10 23:23:01 +00002100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002101posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002102{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002103 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002104 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002105 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002106
2107#ifdef Py_WIN_WIDE_FILENAMES
2108 if (unicode_file_names()) {
2109 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002110 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002111 Py_BEGIN_ALLOW_THREADS
2112 /* PyUnicode_AS_UNICODE OK without thread lock as
2113 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002114 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002115 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002116 if (!res)
2117 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002118 Py_INCREF(Py_None);
2119 return Py_None;
2120 }
2121 /* Drop the argument parsing error as narrow strings
2122 are also valid. */
2123 PyErr_Clear();
2124 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002125 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2126 Py_FileSystemDefaultEncoding, &path, &mode))
2127 return NULL;
2128 Py_BEGIN_ALLOW_THREADS
2129 /* PyUnicode_AS_UNICODE OK without thread lock as
2130 it is a simple dereference. */
2131 res = CreateDirectoryA(path, NULL);
2132 Py_END_ALLOW_THREADS
2133 if (!res) {
2134 win32_error("mkdir", path);
2135 PyMem_Free(path);
2136 return NULL;
2137 }
2138 PyMem_Free(path);
2139 Py_INCREF(Py_None);
2140 return Py_None;
2141#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002142
Tim Peters5aa91602002-01-30 05:46:57 +00002143 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002144 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002145 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002147#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002148 res = mkdir(path);
2149#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002150 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002151#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002152 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002153 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002154 return posix_error_with_allocated_filename(path);
2155 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002156 Py_INCREF(Py_None);
2157 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002158#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002159}
2160
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002161
Neal Norwitz1818ed72006-03-26 00:29:48 +00002162/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2163#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002164#include <sys/resource.h>
2165#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002166
Neal Norwitz1818ed72006-03-26 00:29:48 +00002167
2168#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002169PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002170"nice(inc) -> new_priority\n\n\
2171Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002172
Barry Warsaw53699e91996-12-10 23:23:01 +00002173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002174posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002175{
2176 int increment, value;
2177
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002178 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002179 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002180
2181 /* There are two flavours of 'nice': one that returns the new
2182 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002183 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2184 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002185
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002186 If we are of the nice family that returns the new priority, we
2187 need to clear errno before the call, and check if errno is filled
2188 before calling posix_error() on a returnvalue of -1, because the
2189 -1 may be the actual new priority! */
2190
2191 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002192 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002193#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002194 if (value == 0)
2195 value = getpriority(PRIO_PROCESS, 0);
2196#endif
2197 if (value == -1 && errno != 0)
2198 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002199 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002200 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002201}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002202#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002204PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002205"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002206Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207
Barry Warsaw53699e91996-12-10 23:23:01 +00002208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002209posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002210{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002211#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002212 PyObject *o1, *o2;
2213 char *p1, *p2;
2214 BOOL result;
2215 if (unicode_file_names()) {
2216 if (!PyArg_ParseTuple(args, "O&O&:rename",
2217 convert_to_unicode, &o1,
2218 convert_to_unicode, &o2))
2219 PyErr_Clear();
2220 else {
2221 Py_BEGIN_ALLOW_THREADS
2222 result = MoveFileW(PyUnicode_AsUnicode(o1),
2223 PyUnicode_AsUnicode(o2));
2224 Py_END_ALLOW_THREADS
2225 Py_DECREF(o1);
2226 Py_DECREF(o2);
2227 if (!result)
2228 return win32_error("rename", NULL);
2229 Py_INCREF(Py_None);
2230 return Py_None;
2231 }
2232 }
2233 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2234 return NULL;
2235 Py_BEGIN_ALLOW_THREADS
2236 result = MoveFileA(p1, p2);
2237 Py_END_ALLOW_THREADS
2238 if (!result)
2239 return win32_error("rename", NULL);
2240 Py_INCREF(Py_None);
2241 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002242#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002243 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002244#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002245}
2246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002248PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002249"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002250Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002251
Barry Warsaw53699e91996-12-10 23:23:01 +00002252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002253posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002254{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002256 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002257#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002258 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002259#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002260}
2261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002263PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002264"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002265Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002266
Barry Warsaw53699e91996-12-10 23:23:01 +00002267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002268posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002269{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002270#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002271 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002272#else
2273 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2274#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275}
2276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002277
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002278#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002280"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002281Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282
Barry Warsaw53699e91996-12-10 23:23:01 +00002283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002284posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002285{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002286 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002287 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002288 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002289 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002290 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002291 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002292 Py_END_ALLOW_THREADS
2293 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002294}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002295#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002299"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002301
Barry Warsaw53699e91996-12-10 23:23:01 +00002302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002303posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002304{
2305 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002306 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002307 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002308 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309 if (i < 0)
2310 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002311 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002312}
2313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002314
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002315PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002316"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002317Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002320"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002322
Barry Warsaw53699e91996-12-10 23:23:01 +00002323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002324posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002325{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002326#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002327 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002328#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002329 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002331}
2332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002333
Guido van Rossumb6775db1994-08-01 11:34:53 +00002334#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002335PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002336"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002337Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002338
Barry Warsaw53699e91996-12-10 23:23:01 +00002339static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002340posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002341{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002342 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002343 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002344
Barry Warsaw53699e91996-12-10 23:23:01 +00002345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002346 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002347 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002348 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002349 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002350 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002351 u.sysname,
2352 u.nodename,
2353 u.release,
2354 u.version,
2355 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002356}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002357#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002358
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002359static int
2360extract_time(PyObject *t, long* sec, long* usec)
2361{
2362 long intval;
2363 if (PyFloat_Check(t)) {
2364 double tval = PyFloat_AsDouble(t);
2365 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2366 if (!intobj)
2367 return -1;
2368 intval = PyInt_AsLong(intobj);
2369 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002370 if (intval == -1 && PyErr_Occurred())
2371 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002372 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002373 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002374 if (*usec < 0)
2375 /* If rounding gave us a negative number,
2376 truncate. */
2377 *usec = 0;
2378 return 0;
2379 }
2380 intval = PyInt_AsLong(t);
2381 if (intval == -1 && PyErr_Occurred())
2382 return -1;
2383 *sec = intval;
2384 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002385 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002386}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002388PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002389"utime(path, (atime, utime))\n\
2390utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002391Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002392second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002393
Barry Warsaw53699e91996-12-10 23:23:01 +00002394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002395posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002396{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002397#ifdef Py_WIN_WIDE_FILENAMES
2398 PyObject *arg;
2399 PyUnicodeObject *obwpath;
2400 wchar_t *wpath = NULL;
2401 char *apath = NULL;
2402 HANDLE hFile;
2403 long atimesec, mtimesec, ausec, musec;
2404 FILETIME atime, mtime;
2405 PyObject *result = NULL;
2406
2407 if (unicode_file_names()) {
2408 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2409 wpath = PyUnicode_AS_UNICODE(obwpath);
2410 Py_BEGIN_ALLOW_THREADS
2411 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2412 NULL, OPEN_EXISTING, 0, NULL);
2413 Py_END_ALLOW_THREADS
2414 if (hFile == INVALID_HANDLE_VALUE)
2415 return win32_error_unicode("utime", wpath);
2416 } else
2417 /* Drop the argument parsing error as narrow strings
2418 are also valid. */
2419 PyErr_Clear();
2420 }
2421 if (!wpath) {
2422 if (!PyArg_ParseTuple(args, "etO:utime",
2423 Py_FileSystemDefaultEncoding, &apath, &arg))
2424 return NULL;
2425 Py_BEGIN_ALLOW_THREADS
2426 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2427 NULL, OPEN_EXISTING, 0, NULL);
2428 Py_END_ALLOW_THREADS
2429 if (hFile == INVALID_HANDLE_VALUE) {
2430 win32_error("utime", apath);
2431 PyMem_Free(apath);
2432 return NULL;
2433 }
2434 PyMem_Free(apath);
2435 }
2436
2437 if (arg == Py_None) {
2438 SYSTEMTIME now;
2439 GetSystemTime(&now);
2440 if (!SystemTimeToFileTime(&now, &mtime) ||
2441 !SystemTimeToFileTime(&now, &atime)) {
2442 win32_error("utime", NULL);
2443 goto done;
2444 }
2445 }
2446 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2447 PyErr_SetString(PyExc_TypeError,
2448 "utime() arg 2 must be a tuple (atime, mtime)");
2449 goto done;
2450 }
2451 else {
2452 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2453 &atimesec, &ausec) == -1)
2454 goto done;
2455 time_t_to_FILE_TIME(atimesec, ausec, &atime);
2456 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2457 &mtimesec, &musec) == -1)
2458 goto done;
2459 time_t_to_FILE_TIME(mtimesec, musec, &mtime);
2460 }
2461 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2462 /* Avoid putting the file name into the error here,
2463 as that may confuse the user into believing that
2464 something is wrong with the file, when it also
2465 could be the time stamp that gives a problem. */
2466 win32_error("utime", NULL);
2467 }
2468 Py_INCREF(Py_None);
2469 result = Py_None;
2470done:
2471 CloseHandle(hFile);
2472 return result;
2473#else /* Py_WIN_WIDE_FILENAMES */
2474
Neal Norwitz2adf2102004-06-09 01:46:02 +00002475 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002476 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002477 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002478 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002479
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002480#if defined(HAVE_UTIMES)
2481 struct timeval buf[2];
2482#define ATIME buf[0].tv_sec
2483#define MTIME buf[1].tv_sec
2484#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002485/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002486 struct utimbuf buf;
2487#define ATIME buf.actime
2488#define MTIME buf.modtime
2489#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002490#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002491 time_t buf[2];
2492#define ATIME buf[0]
2493#define MTIME buf[1]
2494#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002495#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002496
Mark Hammond817c9292003-12-03 01:22:38 +00002497
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002498 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002499 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002500 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002501 if (arg == Py_None) {
2502 /* optional time values not given */
2503 Py_BEGIN_ALLOW_THREADS
2504 res = utime(path, NULL);
2505 Py_END_ALLOW_THREADS
2506 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002507 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002508 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002509 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002510 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002511 return NULL;
2512 }
2513 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002514 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002515 &atime, &ausec) == -1) {
2516 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002517 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002518 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002519 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002520 &mtime, &musec) == -1) {
2521 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002522 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002523 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002524 ATIME = atime;
2525 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002526#ifdef HAVE_UTIMES
2527 buf[0].tv_usec = ausec;
2528 buf[1].tv_usec = musec;
2529 Py_BEGIN_ALLOW_THREADS
2530 res = utimes(path, buf);
2531 Py_END_ALLOW_THREADS
2532#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002533 Py_BEGIN_ALLOW_THREADS
2534 res = utime(path, UTIME_ARG);
2535 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002536#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002537 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002538 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002539 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002540 }
Neal Norwitz96652712004-06-06 20:40:27 +00002541 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002542 Py_INCREF(Py_None);
2543 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002544#undef UTIME_ARG
2545#undef ATIME
2546#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002547#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002548}
2549
Guido van Rossum85e3b011991-06-03 12:42:10 +00002550
Guido van Rossum3b066191991-06-04 19:40:25 +00002551/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002553PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002554"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002555Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002556
Barry Warsaw53699e91996-12-10 23:23:01 +00002557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002558posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002559{
2560 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002561 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002562 return NULL;
2563 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002564 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002565}
2566
Martin v. Löwis114619e2002-10-07 06:44:21 +00002567#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2568static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002569free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002570{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002571 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002572 for (i = 0; i < count; i++)
2573 PyMem_Free(array[i]);
2574 PyMem_DEL(array);
2575}
2576#endif
2577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002578
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002579#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002580PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002581"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002582Execute an executable path with arguments, replacing current process.\n\
2583\n\
2584 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002585 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002586
Barry Warsaw53699e91996-12-10 23:23:01 +00002587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002588posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002589{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002590 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002591 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002592 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002593 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002594 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002595
Guido van Rossum89b33251993-10-22 14:26:06 +00002596 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002597 argv is a list or tuple of strings. */
2598
Martin v. Löwis114619e2002-10-07 06:44:21 +00002599 if (!PyArg_ParseTuple(args, "etO:execv",
2600 Py_FileSystemDefaultEncoding,
2601 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002602 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002603 if (PyList_Check(argv)) {
2604 argc = PyList_Size(argv);
2605 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002606 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002607 else if (PyTuple_Check(argv)) {
2608 argc = PyTuple_Size(argv);
2609 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002610 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002611 else {
Fred Drake661ea262000-10-24 19:57:45 +00002612 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002613 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002614 return NULL;
2615 }
2616
Barry Warsaw53699e91996-12-10 23:23:01 +00002617 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002618 if (argvlist == NULL) {
2619 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002620 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002621 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002622 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002623 if (!PyArg_Parse((*getitem)(argv, i), "et",
2624 Py_FileSystemDefaultEncoding,
2625 &argvlist[i])) {
2626 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002627 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002628 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002629 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002630 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002631
Guido van Rossum85e3b011991-06-03 12:42:10 +00002632 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002633 }
2634 argvlist[argc] = NULL;
2635
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002636 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002637
Guido van Rossum85e3b011991-06-03 12:42:10 +00002638 /* If we get here it's definitely an error */
2639
Martin v. Löwis114619e2002-10-07 06:44:21 +00002640 free_string_array(argvlist, argc);
2641 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002642 return posix_error();
2643}
2644
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002646PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002647"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002648Execute a path with arguments and environment, replacing current process.\n\
2649\n\
2650 path: path of executable file\n\
2651 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002652 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002653
Barry Warsaw53699e91996-12-10 23:23:01 +00002654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002655posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002656{
2657 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002658 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002659 char **argvlist;
2660 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002661 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002662 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002663 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002664 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002665
2666 /* execve has three arguments: (path, argv, env), where
2667 argv is a list or tuple of strings and env is a dictionary
2668 like posix.environ. */
2669
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 if (!PyArg_ParseTuple(args, "etOO:execve",
2671 Py_FileSystemDefaultEncoding,
2672 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002673 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002674 if (PyList_Check(argv)) {
2675 argc = PyList_Size(argv);
2676 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002677 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002678 else if (PyTuple_Check(argv)) {
2679 argc = PyTuple_Size(argv);
2680 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002681 }
2682 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002683 PyErr_SetString(PyExc_TypeError,
2684 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002685 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002686 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002687 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002688 PyErr_SetString(PyExc_TypeError,
2689 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002691 }
2692
Barry Warsaw53699e91996-12-10 23:23:01 +00002693 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002694 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002695 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002696 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002697 }
2698 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002699 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002700 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002701 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002702 &argvlist[i]))
2703 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002704 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002705 goto fail_1;
2706 }
2707 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002708 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002709 argvlist[argc] = NULL;
2710
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002711 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002712 if (i < 0)
2713 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002714 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002715 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002716 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002717 goto fail_1;
2718 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002719 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002720 keys = PyMapping_Keys(env);
2721 vals = PyMapping_Values(env);
2722 if (!keys || !vals)
2723 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002724 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2725 PyErr_SetString(PyExc_TypeError,
2726 "execve(): env.keys() or env.values() is not a list");
2727 goto fail_2;
2728 }
Tim Peters5aa91602002-01-30 05:46:57 +00002729
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002730 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002731 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002732 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002733
2734 key = PyList_GetItem(keys, pos);
2735 val = PyList_GetItem(vals, pos);
2736 if (!key || !val)
2737 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002738
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002739 if (!PyArg_Parse(
2740 key,
2741 "s;execve() arg 3 contains a non-string key",
2742 &k) ||
2743 !PyArg_Parse(
2744 val,
2745 "s;execve() arg 3 contains a non-string value",
2746 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002747 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002748 goto fail_2;
2749 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002750
2751#if defined(PYOS_OS2)
2752 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2753 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2754#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002755 len = PyString_Size(key) + PyString_Size(val) + 2;
2756 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002757 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002758 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002759 goto fail_2;
2760 }
Tim Petersc8996f52001-12-03 20:41:00 +00002761 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002762 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002763#if defined(PYOS_OS2)
2764 }
2765#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002766 }
2767 envlist[envc] = 0;
2768
2769 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002770
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002771 /* If we get here it's definitely an error */
2772
2773 (void) posix_error();
2774
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002775 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002776 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002777 PyMem_DEL(envlist[envc]);
2778 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002779 fail_1:
2780 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002781 Py_XDECREF(vals);
2782 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002783 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002784 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002785 return NULL;
2786}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002787#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002789
Guido van Rossuma1065681999-01-25 23:20:23 +00002790#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002791PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002792"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002793Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002794\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002795 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002796 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002797 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002798
2799static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002800posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002801{
2802 char *path;
2803 PyObject *argv;
2804 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002805 int mode, i;
2806 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002807 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002808 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002809
2810 /* spawnv has three arguments: (mode, path, argv), where
2811 argv is a list or tuple of strings. */
2812
Martin v. Löwis114619e2002-10-07 06:44:21 +00002813 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2814 Py_FileSystemDefaultEncoding,
2815 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002816 return NULL;
2817 if (PyList_Check(argv)) {
2818 argc = PyList_Size(argv);
2819 getitem = PyList_GetItem;
2820 }
2821 else if (PyTuple_Check(argv)) {
2822 argc = PyTuple_Size(argv);
2823 getitem = PyTuple_GetItem;
2824 }
2825 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002826 PyErr_SetString(PyExc_TypeError,
2827 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002828 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002829 return NULL;
2830 }
2831
2832 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002833 if (argvlist == NULL) {
2834 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002835 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002836 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002837 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002838 if (!PyArg_Parse((*getitem)(argv, i), "et",
2839 Py_FileSystemDefaultEncoding,
2840 &argvlist[i])) {
2841 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002842 PyErr_SetString(
2843 PyExc_TypeError,
2844 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002845 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002846 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002847 }
2848 }
2849 argvlist[argc] = NULL;
2850
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002851#if defined(PYOS_OS2) && defined(PYCC_GCC)
2852 Py_BEGIN_ALLOW_THREADS
2853 spawnval = spawnv(mode, path, argvlist);
2854 Py_END_ALLOW_THREADS
2855#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002856 if (mode == _OLD_P_OVERLAY)
2857 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002858
Tim Peters25059d32001-12-07 20:35:43 +00002859 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002860 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002861 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002862#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002863
Martin v. Löwis114619e2002-10-07 06:44:21 +00002864 free_string_array(argvlist, argc);
2865 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002866
Fred Drake699f3522000-06-29 21:12:41 +00002867 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002868 return posix_error();
2869 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002870#if SIZEOF_LONG == SIZEOF_VOID_P
2871 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002872#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002873 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002874#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002875}
2876
2877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002880Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002881\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002882 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002883 path: path of executable file\n\
2884 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002885 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002886
2887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002888posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002889{
2890 char *path;
2891 PyObject *argv, *env;
2892 char **argvlist;
2893 char **envlist;
2894 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002895 int mode, pos, envc;
2896 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002897 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002898 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002899 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002900
2901 /* spawnve has four arguments: (mode, path, argv, env), where
2902 argv is a list or tuple of strings and env is a dictionary
2903 like posix.environ. */
2904
Martin v. Löwis114619e2002-10-07 06:44:21 +00002905 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2906 Py_FileSystemDefaultEncoding,
2907 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002908 return NULL;
2909 if (PyList_Check(argv)) {
2910 argc = PyList_Size(argv);
2911 getitem = PyList_GetItem;
2912 }
2913 else if (PyTuple_Check(argv)) {
2914 argc = PyTuple_Size(argv);
2915 getitem = PyTuple_GetItem;
2916 }
2917 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002918 PyErr_SetString(PyExc_TypeError,
2919 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002920 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002921 }
2922 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002923 PyErr_SetString(PyExc_TypeError,
2924 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002925 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002926 }
2927
2928 argvlist = PyMem_NEW(char *, argc+1);
2929 if (argvlist == NULL) {
2930 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002931 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002932 }
2933 for (i = 0; i < argc; i++) {
2934 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002935 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002936 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002937 &argvlist[i]))
2938 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002939 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002940 goto fail_1;
2941 }
2942 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002943 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002944 argvlist[argc] = NULL;
2945
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002946 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002947 if (i < 0)
2948 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002949 envlist = PyMem_NEW(char *, i + 1);
2950 if (envlist == NULL) {
2951 PyErr_NoMemory();
2952 goto fail_1;
2953 }
2954 envc = 0;
2955 keys = PyMapping_Keys(env);
2956 vals = PyMapping_Values(env);
2957 if (!keys || !vals)
2958 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002959 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2960 PyErr_SetString(PyExc_TypeError,
2961 "spawnve(): env.keys() or env.values() is not a list");
2962 goto fail_2;
2963 }
Tim Peters5aa91602002-01-30 05:46:57 +00002964
Guido van Rossuma1065681999-01-25 23:20:23 +00002965 for (pos = 0; pos < i; pos++) {
2966 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002967 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002968
2969 key = PyList_GetItem(keys, pos);
2970 val = PyList_GetItem(vals, pos);
2971 if (!key || !val)
2972 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002973
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002974 if (!PyArg_Parse(
2975 key,
2976 "s;spawnve() arg 3 contains a non-string key",
2977 &k) ||
2978 !PyArg_Parse(
2979 val,
2980 "s;spawnve() arg 3 contains a non-string value",
2981 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002982 {
2983 goto fail_2;
2984 }
Tim Petersc8996f52001-12-03 20:41:00 +00002985 len = PyString_Size(key) + PyString_Size(val) + 2;
2986 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002987 if (p == NULL) {
2988 PyErr_NoMemory();
2989 goto fail_2;
2990 }
Tim Petersc8996f52001-12-03 20:41:00 +00002991 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002992 envlist[envc++] = p;
2993 }
2994 envlist[envc] = 0;
2995
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002996#if defined(PYOS_OS2) && defined(PYCC_GCC)
2997 Py_BEGIN_ALLOW_THREADS
2998 spawnval = spawnve(mode, path, argvlist, envlist);
2999 Py_END_ALLOW_THREADS
3000#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003001 if (mode == _OLD_P_OVERLAY)
3002 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003003
3004 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003005 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003006 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003007#endif
Tim Peters25059d32001-12-07 20:35:43 +00003008
Fred Drake699f3522000-06-29 21:12:41 +00003009 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003010 (void) posix_error();
3011 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003012#if SIZEOF_LONG == SIZEOF_VOID_P
3013 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003014#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003015 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003016#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003017
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003018 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003019 while (--envc >= 0)
3020 PyMem_DEL(envlist[envc]);
3021 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003022 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003023 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003024 Py_XDECREF(vals);
3025 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003026 fail_0:
3027 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003028 return res;
3029}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003030
3031/* OS/2 supports spawnvp & spawnvpe natively */
3032#if defined(PYOS_OS2)
3033PyDoc_STRVAR(posix_spawnvp__doc__,
3034"spawnvp(mode, file, args)\n\n\
3035Execute the program 'file' in a new process, using the environment\n\
3036search path to find the file.\n\
3037\n\
3038 mode: mode of process creation\n\
3039 file: executable file name\n\
3040 args: tuple or list of strings");
3041
3042static PyObject *
3043posix_spawnvp(PyObject *self, PyObject *args)
3044{
3045 char *path;
3046 PyObject *argv;
3047 char **argvlist;
3048 int mode, i, argc;
3049 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003050 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003051
3052 /* spawnvp has three arguments: (mode, path, argv), where
3053 argv is a list or tuple of strings. */
3054
3055 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3056 Py_FileSystemDefaultEncoding,
3057 &path, &argv))
3058 return NULL;
3059 if (PyList_Check(argv)) {
3060 argc = PyList_Size(argv);
3061 getitem = PyList_GetItem;
3062 }
3063 else if (PyTuple_Check(argv)) {
3064 argc = PyTuple_Size(argv);
3065 getitem = PyTuple_GetItem;
3066 }
3067 else {
3068 PyErr_SetString(PyExc_TypeError,
3069 "spawnvp() arg 2 must be a tuple or list");
3070 PyMem_Free(path);
3071 return NULL;
3072 }
3073
3074 argvlist = PyMem_NEW(char *, argc+1);
3075 if (argvlist == NULL) {
3076 PyMem_Free(path);
3077 return PyErr_NoMemory();
3078 }
3079 for (i = 0; i < argc; i++) {
3080 if (!PyArg_Parse((*getitem)(argv, i), "et",
3081 Py_FileSystemDefaultEncoding,
3082 &argvlist[i])) {
3083 free_string_array(argvlist, i);
3084 PyErr_SetString(
3085 PyExc_TypeError,
3086 "spawnvp() arg 2 must contain only strings");
3087 PyMem_Free(path);
3088 return NULL;
3089 }
3090 }
3091 argvlist[argc] = NULL;
3092
3093 Py_BEGIN_ALLOW_THREADS
3094#if defined(PYCC_GCC)
3095 spawnval = spawnvp(mode, path, argvlist);
3096#else
3097 spawnval = _spawnvp(mode, path, argvlist);
3098#endif
3099 Py_END_ALLOW_THREADS
3100
3101 free_string_array(argvlist, argc);
3102 PyMem_Free(path);
3103
3104 if (spawnval == -1)
3105 return posix_error();
3106 else
3107 return Py_BuildValue("l", (long) spawnval);
3108}
3109
3110
3111PyDoc_STRVAR(posix_spawnvpe__doc__,
3112"spawnvpe(mode, file, args, env)\n\n\
3113Execute the program 'file' in a new process, using the environment\n\
3114search path to find the file.\n\
3115\n\
3116 mode: mode of process creation\n\
3117 file: executable file name\n\
3118 args: tuple or list of arguments\n\
3119 env: dictionary of strings mapping to strings");
3120
3121static PyObject *
3122posix_spawnvpe(PyObject *self, PyObject *args)
3123{
3124 char *path;
3125 PyObject *argv, *env;
3126 char **argvlist;
3127 char **envlist;
3128 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3129 int mode, i, pos, argc, envc;
3130 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003131 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003132 int lastarg = 0;
3133
3134 /* spawnvpe has four arguments: (mode, path, argv, env), where
3135 argv is a list or tuple of strings and env is a dictionary
3136 like posix.environ. */
3137
3138 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3139 Py_FileSystemDefaultEncoding,
3140 &path, &argv, &env))
3141 return NULL;
3142 if (PyList_Check(argv)) {
3143 argc = PyList_Size(argv);
3144 getitem = PyList_GetItem;
3145 }
3146 else if (PyTuple_Check(argv)) {
3147 argc = PyTuple_Size(argv);
3148 getitem = PyTuple_GetItem;
3149 }
3150 else {
3151 PyErr_SetString(PyExc_TypeError,
3152 "spawnvpe() arg 2 must be a tuple or list");
3153 goto fail_0;
3154 }
3155 if (!PyMapping_Check(env)) {
3156 PyErr_SetString(PyExc_TypeError,
3157 "spawnvpe() arg 3 must be a mapping object");
3158 goto fail_0;
3159 }
3160
3161 argvlist = PyMem_NEW(char *, argc+1);
3162 if (argvlist == NULL) {
3163 PyErr_NoMemory();
3164 goto fail_0;
3165 }
3166 for (i = 0; i < argc; i++) {
3167 if (!PyArg_Parse((*getitem)(argv, i),
3168 "et;spawnvpe() arg 2 must contain only strings",
3169 Py_FileSystemDefaultEncoding,
3170 &argvlist[i]))
3171 {
3172 lastarg = i;
3173 goto fail_1;
3174 }
3175 }
3176 lastarg = argc;
3177 argvlist[argc] = NULL;
3178
3179 i = PyMapping_Size(env);
3180 if (i < 0)
3181 goto fail_1;
3182 envlist = PyMem_NEW(char *, i + 1);
3183 if (envlist == NULL) {
3184 PyErr_NoMemory();
3185 goto fail_1;
3186 }
3187 envc = 0;
3188 keys = PyMapping_Keys(env);
3189 vals = PyMapping_Values(env);
3190 if (!keys || !vals)
3191 goto fail_2;
3192 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3193 PyErr_SetString(PyExc_TypeError,
3194 "spawnvpe(): env.keys() or env.values() is not a list");
3195 goto fail_2;
3196 }
3197
3198 for (pos = 0; pos < i; pos++) {
3199 char *p, *k, *v;
3200 size_t len;
3201
3202 key = PyList_GetItem(keys, pos);
3203 val = PyList_GetItem(vals, pos);
3204 if (!key || !val)
3205 goto fail_2;
3206
3207 if (!PyArg_Parse(
3208 key,
3209 "s;spawnvpe() arg 3 contains a non-string key",
3210 &k) ||
3211 !PyArg_Parse(
3212 val,
3213 "s;spawnvpe() arg 3 contains a non-string value",
3214 &v))
3215 {
3216 goto fail_2;
3217 }
3218 len = PyString_Size(key) + PyString_Size(val) + 2;
3219 p = PyMem_NEW(char, len);
3220 if (p == NULL) {
3221 PyErr_NoMemory();
3222 goto fail_2;
3223 }
3224 PyOS_snprintf(p, len, "%s=%s", k, v);
3225 envlist[envc++] = p;
3226 }
3227 envlist[envc] = 0;
3228
3229 Py_BEGIN_ALLOW_THREADS
3230#if defined(PYCC_GCC)
3231 spawnval = spawnve(mode, path, argvlist, envlist);
3232#else
3233 spawnval = _spawnve(mode, path, argvlist, envlist);
3234#endif
3235 Py_END_ALLOW_THREADS
3236
3237 if (spawnval == -1)
3238 (void) posix_error();
3239 else
3240 res = Py_BuildValue("l", (long) spawnval);
3241
3242 fail_2:
3243 while (--envc >= 0)
3244 PyMem_DEL(envlist[envc]);
3245 PyMem_DEL(envlist);
3246 fail_1:
3247 free_string_array(argvlist, lastarg);
3248 Py_XDECREF(vals);
3249 Py_XDECREF(keys);
3250 fail_0:
3251 PyMem_Free(path);
3252 return res;
3253}
3254#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003255#endif /* HAVE_SPAWNV */
3256
3257
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003258#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003259PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003260"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003261Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3262\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003264
3265static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003266posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003267{
Neal Norwitze241ce82003-02-17 18:17:05 +00003268 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003269 if (pid == -1)
3270 return posix_error();
3271 PyOS_AfterFork();
3272 return PyInt_FromLong((long)pid);
3273}
3274#endif
3275
3276
Guido van Rossumad0ee831995-03-01 10:34:45 +00003277#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003278PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003279"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003281Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003282
Barry Warsaw53699e91996-12-10 23:23:01 +00003283static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003284posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003285{
Neal Norwitze241ce82003-02-17 18:17:05 +00003286 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003287 if (pid == -1)
3288 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003289 if (pid == 0)
3290 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003291 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003292}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003293#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003294
Neal Norwitzb59798b2003-03-21 01:43:31 +00003295/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003296/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3297#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003298#define DEV_PTY_FILE "/dev/ptc"
3299#define HAVE_DEV_PTMX
3300#else
3301#define DEV_PTY_FILE "/dev/ptmx"
3302#endif
3303
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003304#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003305#ifdef HAVE_PTY_H
3306#include <pty.h>
3307#else
3308#ifdef HAVE_LIBUTIL_H
3309#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003310#endif /* HAVE_LIBUTIL_H */
3311#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003312#ifdef HAVE_STROPTS_H
3313#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003314#endif
3315#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003316
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003317#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003318PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003319"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003320Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003321
3322static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003323posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003324{
3325 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003326#ifndef HAVE_OPENPTY
3327 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003328#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003329#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003330 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003331#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003332 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003333#endif
3334#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003335
Thomas Wouters70c21a12000-07-14 14:28:33 +00003336#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003337 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3338 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003339#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003340 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3341 if (slave_name == NULL)
3342 return posix_error();
3343
3344 slave_fd = open(slave_name, O_RDWR);
3345 if (slave_fd < 0)
3346 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003347#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003348 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003349 if (master_fd < 0)
3350 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003351 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003352 /* change permission of slave */
3353 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003354 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003355 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003356 }
3357 /* unlock slave */
3358 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003359 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003360 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003361 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003362 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003363 slave_name = ptsname(master_fd); /* get name of slave */
3364 if (slave_name == NULL)
3365 return posix_error();
3366 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3367 if (slave_fd < 0)
3368 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003369#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003370 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3371 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003372#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003373 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003374#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003375#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003376#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003377
Fred Drake8cef4cf2000-06-28 16:40:38 +00003378 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003379
Fred Drake8cef4cf2000-06-28 16:40:38 +00003380}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003381#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003382
3383#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003384PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003385"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003386Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3387Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003388To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003389
3390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003391posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003392{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003393 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003394
Fred Drake8cef4cf2000-06-28 16:40:38 +00003395 pid = forkpty(&master_fd, NULL, NULL, NULL);
3396 if (pid == -1)
3397 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003398 if (pid == 0)
3399 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003400 return Py_BuildValue("(ii)", pid, master_fd);
3401}
3402#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003403
Guido van Rossumad0ee831995-03-01 10:34:45 +00003404#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003405PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003406"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003407Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003408
Barry Warsaw53699e91996-12-10 23:23:01 +00003409static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003410posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003411{
Barry Warsaw53699e91996-12-10 23:23:01 +00003412 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003413}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003414#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003416
Guido van Rossumad0ee831995-03-01 10:34:45 +00003417#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003418PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003419"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003420Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003421
Barry Warsaw53699e91996-12-10 23:23:01 +00003422static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003423posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003424{
Barry Warsaw53699e91996-12-10 23:23:01 +00003425 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003426}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003427#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003429
Guido van Rossumad0ee831995-03-01 10:34:45 +00003430#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003432"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003434
Barry Warsaw53699e91996-12-10 23:23:01 +00003435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003436posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003437{
Barry Warsaw53699e91996-12-10 23:23:01 +00003438 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003439}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003440#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003443PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003444"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003445Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
Barry Warsaw53699e91996-12-10 23:23:01 +00003447static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003448posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003449{
Barry Warsaw53699e91996-12-10 23:23:01 +00003450 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003451}
3452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003453
Fred Drakec9680921999-12-13 16:37:25 +00003454#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003455PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003456"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003457Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003458
3459static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003460posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003461{
3462 PyObject *result = NULL;
3463
Fred Drakec9680921999-12-13 16:37:25 +00003464#ifdef NGROUPS_MAX
3465#define MAX_GROUPS NGROUPS_MAX
3466#else
3467 /* defined to be 16 on Solaris7, so this should be a small number */
3468#define MAX_GROUPS 64
3469#endif
3470 gid_t grouplist[MAX_GROUPS];
3471 int n;
3472
3473 n = getgroups(MAX_GROUPS, grouplist);
3474 if (n < 0)
3475 posix_error();
3476 else {
3477 result = PyList_New(n);
3478 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003479 int i;
3480 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003481 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003482 if (o == NULL) {
3483 Py_DECREF(result);
3484 result = NULL;
3485 break;
3486 }
3487 PyList_SET_ITEM(result, i, o);
3488 }
3489 }
3490 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003491
Fred Drakec9680921999-12-13 16:37:25 +00003492 return result;
3493}
3494#endif
3495
Martin v. Löwis606edc12002-06-13 21:09:11 +00003496#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003497PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003498"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003499Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003500
3501static PyObject *
3502posix_getpgid(PyObject *self, PyObject *args)
3503{
3504 int pid, pgid;
3505 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3506 return NULL;
3507 pgid = getpgid(pid);
3508 if (pgid < 0)
3509 return posix_error();
3510 return PyInt_FromLong((long)pgid);
3511}
3512#endif /* HAVE_GETPGID */
3513
3514
Guido van Rossumb6775db1994-08-01 11:34:53 +00003515#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003516PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003517"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003518Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003519
Barry Warsaw53699e91996-12-10 23:23:01 +00003520static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003521posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003522{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003523#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003524 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003525#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003526 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003527#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003528}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003529#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003531
Guido van Rossumb6775db1994-08-01 11:34:53 +00003532#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003533PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003534"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003535Make this process a session leader.");
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_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003539{
Guido van Rossum64933891994-10-20 21:56:42 +00003540#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003541 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003542#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003543 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003544#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003545 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003546 Py_INCREF(Py_None);
3547 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003548}
3549
Guido van Rossumb6775db1994-08-01 11:34:53 +00003550#endif /* HAVE_SETPGRP */
3551
Guido van Rossumad0ee831995-03-01 10:34:45 +00003552#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003553PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003554"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003555Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003556
Barry Warsaw53699e91996-12-10 23:23:01 +00003557static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003558posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003559{
Barry Warsaw53699e91996-12-10 23:23:01 +00003560 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003561}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003562#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003564
Fred Drake12c6e2d1999-12-14 21:25:03 +00003565#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003566PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003567"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003568Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003569
3570static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003571posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003572{
Neal Norwitze241ce82003-02-17 18:17:05 +00003573 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003574 char *name;
3575 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003576
Fred Drakea30680b2000-12-06 21:24:28 +00003577 errno = 0;
3578 name = getlogin();
3579 if (name == NULL) {
3580 if (errno)
3581 posix_error();
3582 else
3583 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003584 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003585 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003586 else
3587 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003588 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003589
Fred Drake12c6e2d1999-12-14 21:25:03 +00003590 return result;
3591}
3592#endif
3593
Guido van Rossumad0ee831995-03-01 10:34:45 +00003594#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003595PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003596"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003597Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003598
Barry Warsaw53699e91996-12-10 23:23:01 +00003599static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003600posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003601{
Barry Warsaw53699e91996-12-10 23:23:01 +00003602 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003603}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003604#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003606
Guido van Rossumad0ee831995-03-01 10:34:45 +00003607#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003608PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003609"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003610Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003611
Barry Warsaw53699e91996-12-10 23:23:01 +00003612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003613posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003614{
3615 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003616 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003617 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003618#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003619 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3620 APIRET rc;
3621 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003622 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003623
3624 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3625 APIRET rc;
3626 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003627 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003628
3629 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003630 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003631#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003632 if (kill(pid, sig) == -1)
3633 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003634#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_INCREF(Py_None);
3636 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003637}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003638#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003639
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003640#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003641PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003642"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003643Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003644
3645static PyObject *
3646posix_killpg(PyObject *self, PyObject *args)
3647{
3648 int pgid, sig;
3649 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3650 return NULL;
3651 if (killpg(pgid, sig) == -1)
3652 return posix_error();
3653 Py_INCREF(Py_None);
3654 return Py_None;
3655}
3656#endif
3657
Guido van Rossumc0125471996-06-28 18:55:32 +00003658#ifdef HAVE_PLOCK
3659
3660#ifdef HAVE_SYS_LOCK_H
3661#include <sys/lock.h>
3662#endif
3663
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003664PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003665"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003666Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003667
Barry Warsaw53699e91996-12-10 23:23:01 +00003668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003669posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003670{
3671 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003672 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003673 return NULL;
3674 if (plock(op) == -1)
3675 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003676 Py_INCREF(Py_None);
3677 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003678}
3679#endif
3680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003681
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003682#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003683PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003684"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003685Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003686
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003687#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003688#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003689static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003690async_system(const char *command)
3691{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003692 char errormsg[256], args[1024];
3693 RESULTCODES rcodes;
3694 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003695
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003696 char *shell = getenv("COMSPEC");
3697 if (!shell)
3698 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003699
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003700 /* avoid overflowing the argument buffer */
3701 if (strlen(shell) + 3 + strlen(command) >= 1024)
3702 return ERROR_NOT_ENOUGH_MEMORY
3703
3704 args[0] = '\0';
3705 strcat(args, shell);
3706 strcat(args, "/c ");
3707 strcat(args, command);
3708
3709 /* execute asynchronously, inheriting the environment */
3710 rc = DosExecPgm(errormsg,
3711 sizeof(errormsg),
3712 EXEC_ASYNC,
3713 args,
3714 NULL,
3715 &rcodes,
3716 shell);
3717 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003718}
3719
Guido van Rossumd48f2521997-12-05 22:19:34 +00003720static FILE *
3721popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003722{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003723 int oldfd, tgtfd;
3724 HFILE pipeh[2];
3725 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003726
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003727 /* mode determines which of stdin or stdout is reconnected to
3728 * the pipe to the child
3729 */
3730 if (strchr(mode, 'r') != NULL) {
3731 tgt_fd = 1; /* stdout */
3732 } else if (strchr(mode, 'w')) {
3733 tgt_fd = 0; /* stdin */
3734 } else {
3735 *err = ERROR_INVALID_ACCESS;
3736 return NULL;
3737 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003738
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003739 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003740 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3741 *err = rc;
3742 return NULL;
3743 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003744
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003745 /* prevent other threads accessing stdio */
3746 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003747
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003748 /* reconnect stdio and execute child */
3749 oldfd = dup(tgtfd);
3750 close(tgtfd);
3751 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3752 DosClose(pipeh[tgtfd]);
3753 rc = async_system(command);
3754 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003755
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003756 /* restore stdio */
3757 dup2(oldfd, tgtfd);
3758 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003759
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003760 /* allow other threads access to stdio */
3761 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003762
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003763 /* if execution of child was successful return file stream */
3764 if (rc == NO_ERROR)
3765 return fdopen(pipeh[1 - tgtfd], mode);
3766 else {
3767 DosClose(pipeh[1 - tgtfd]);
3768 *err = rc;
3769 return NULL;
3770 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003771}
3772
3773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003774posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003775{
3776 char *name;
3777 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003778 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003779 FILE *fp;
3780 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003781 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003782 return NULL;
3783 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003784 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003785 Py_END_ALLOW_THREADS
3786 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003787 return os2_error(err);
3788
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003789 f = PyFile_FromFile(fp, name, mode, fclose);
3790 if (f != NULL)
3791 PyFile_SetBufSize(f, bufsize);
3792 return f;
3793}
3794
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003795#elif defined(PYCC_GCC)
3796
3797/* standard posix version of popen() support */
3798static PyObject *
3799posix_popen(PyObject *self, PyObject *args)
3800{
3801 char *name;
3802 char *mode = "r";
3803 int bufsize = -1;
3804 FILE *fp;
3805 PyObject *f;
3806 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3807 return NULL;
3808 Py_BEGIN_ALLOW_THREADS
3809 fp = popen(name, mode);
3810 Py_END_ALLOW_THREADS
3811 if (fp == NULL)
3812 return posix_error();
3813 f = PyFile_FromFile(fp, name, mode, pclose);
3814 if (f != NULL)
3815 PyFile_SetBufSize(f, bufsize);
3816 return f;
3817}
3818
3819/* fork() under OS/2 has lots'o'warts
3820 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3821 * most of this code is a ripoff of the win32 code, but using the
3822 * capabilities of EMX's C library routines
3823 */
3824
3825/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3826#define POPEN_1 1
3827#define POPEN_2 2
3828#define POPEN_3 3
3829#define POPEN_4 4
3830
3831static PyObject *_PyPopen(char *, int, int, int);
3832static int _PyPclose(FILE *file);
3833
3834/*
3835 * Internal dictionary mapping popen* file pointers to process handles,
3836 * for use when retrieving the process exit code. See _PyPclose() below
3837 * for more information on this dictionary's use.
3838 */
3839static PyObject *_PyPopenProcs = NULL;
3840
3841/* os2emx version of popen2()
3842 *
3843 * The result of this function is a pipe (file) connected to the
3844 * process's stdin, and a pipe connected to the process's stdout.
3845 */
3846
3847static PyObject *
3848os2emx_popen2(PyObject *self, PyObject *args)
3849{
3850 PyObject *f;
3851 int tm=0;
3852
3853 char *cmdstring;
3854 char *mode = "t";
3855 int bufsize = -1;
3856 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3857 return NULL;
3858
3859 if (*mode == 't')
3860 tm = O_TEXT;
3861 else if (*mode != 'b') {
3862 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3863 return NULL;
3864 } else
3865 tm = O_BINARY;
3866
3867 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3868
3869 return f;
3870}
3871
3872/*
3873 * Variation on os2emx.popen2
3874 *
3875 * The result of this function is 3 pipes - the process's stdin,
3876 * stdout and stderr
3877 */
3878
3879static PyObject *
3880os2emx_popen3(PyObject *self, PyObject *args)
3881{
3882 PyObject *f;
3883 int tm = 0;
3884
3885 char *cmdstring;
3886 char *mode = "t";
3887 int bufsize = -1;
3888 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3889 return NULL;
3890
3891 if (*mode == 't')
3892 tm = O_TEXT;
3893 else if (*mode != 'b') {
3894 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3895 return NULL;
3896 } else
3897 tm = O_BINARY;
3898
3899 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3900
3901 return f;
3902}
3903
3904/*
3905 * Variation on os2emx.popen2
3906 *
Tim Peters11b23062003-04-23 02:39:17 +00003907 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003908 * and stdout+stderr combined as a single pipe.
3909 */
3910
3911static PyObject *
3912os2emx_popen4(PyObject *self, PyObject *args)
3913{
3914 PyObject *f;
3915 int tm = 0;
3916
3917 char *cmdstring;
3918 char *mode = "t";
3919 int bufsize = -1;
3920 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3921 return NULL;
3922
3923 if (*mode == 't')
3924 tm = O_TEXT;
3925 else if (*mode != 'b') {
3926 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3927 return NULL;
3928 } else
3929 tm = O_BINARY;
3930
3931 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3932
3933 return f;
3934}
3935
3936/* a couple of structures for convenient handling of multiple
3937 * file handles and pipes
3938 */
3939struct file_ref
3940{
3941 int handle;
3942 int flags;
3943};
3944
3945struct pipe_ref
3946{
3947 int rd;
3948 int wr;
3949};
3950
3951/* The following code is derived from the win32 code */
3952
3953static PyObject *
3954_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3955{
3956 struct file_ref stdio[3];
3957 struct pipe_ref p_fd[3];
3958 FILE *p_s[3];
3959 int file_count, i, pipe_err, pipe_pid;
3960 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3961 PyObject *f, *p_f[3];
3962
3963 /* file modes for subsequent fdopen's on pipe handles */
3964 if (mode == O_TEXT)
3965 {
3966 rd_mode = "rt";
3967 wr_mode = "wt";
3968 }
3969 else
3970 {
3971 rd_mode = "rb";
3972 wr_mode = "wb";
3973 }
3974
3975 /* prepare shell references */
3976 if ((shell = getenv("EMXSHELL")) == NULL)
3977 if ((shell = getenv("COMSPEC")) == NULL)
3978 {
3979 errno = ENOENT;
3980 return posix_error();
3981 }
3982
3983 sh_name = _getname(shell);
3984 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3985 opt = "/c";
3986 else
3987 opt = "-c";
3988
3989 /* save current stdio fds + their flags, and set not inheritable */
3990 i = pipe_err = 0;
3991 while (pipe_err >= 0 && i < 3)
3992 {
3993 pipe_err = stdio[i].handle = dup(i);
3994 stdio[i].flags = fcntl(i, F_GETFD, 0);
3995 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3996 i++;
3997 }
3998 if (pipe_err < 0)
3999 {
4000 /* didn't get them all saved - clean up and bail out */
4001 int saved_err = errno;
4002 while (i-- > 0)
4003 {
4004 close(stdio[i].handle);
4005 }
4006 errno = saved_err;
4007 return posix_error();
4008 }
4009
4010 /* create pipe ends */
4011 file_count = 2;
4012 if (n == POPEN_3)
4013 file_count = 3;
4014 i = pipe_err = 0;
4015 while ((pipe_err == 0) && (i < file_count))
4016 pipe_err = pipe((int *)&p_fd[i++]);
4017 if (pipe_err < 0)
4018 {
4019 /* didn't get them all made - clean up and bail out */
4020 while (i-- > 0)
4021 {
4022 close(p_fd[i].wr);
4023 close(p_fd[i].rd);
4024 }
4025 errno = EPIPE;
4026 return posix_error();
4027 }
4028
4029 /* change the actual standard IO streams over temporarily,
4030 * making the retained pipe ends non-inheritable
4031 */
4032 pipe_err = 0;
4033
4034 /* - stdin */
4035 if (dup2(p_fd[0].rd, 0) == 0)
4036 {
4037 close(p_fd[0].rd);
4038 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4039 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4040 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4041 {
4042 close(p_fd[0].wr);
4043 pipe_err = -1;
4044 }
4045 }
4046 else
4047 {
4048 pipe_err = -1;
4049 }
4050
4051 /* - stdout */
4052 if (pipe_err == 0)
4053 {
4054 if (dup2(p_fd[1].wr, 1) == 1)
4055 {
4056 close(p_fd[1].wr);
4057 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4058 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4059 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4060 {
4061 close(p_fd[1].rd);
4062 pipe_err = -1;
4063 }
4064 }
4065 else
4066 {
4067 pipe_err = -1;
4068 }
4069 }
4070
4071 /* - stderr, as required */
4072 if (pipe_err == 0)
4073 switch (n)
4074 {
4075 case POPEN_3:
4076 {
4077 if (dup2(p_fd[2].wr, 2) == 2)
4078 {
4079 close(p_fd[2].wr);
4080 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4081 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4082 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4083 {
4084 close(p_fd[2].rd);
4085 pipe_err = -1;
4086 }
4087 }
4088 else
4089 {
4090 pipe_err = -1;
4091 }
4092 break;
4093 }
4094
4095 case POPEN_4:
4096 {
4097 if (dup2(1, 2) != 2)
4098 {
4099 pipe_err = -1;
4100 }
4101 break;
4102 }
4103 }
4104
4105 /* spawn the child process */
4106 if (pipe_err == 0)
4107 {
4108 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4109 if (pipe_pid == -1)
4110 {
4111 pipe_err = -1;
4112 }
4113 else
4114 {
4115 /* save the PID into the FILE structure
4116 * NOTE: this implementation doesn't actually
4117 * take advantage of this, but do it for
4118 * completeness - AIM Apr01
4119 */
4120 for (i = 0; i < file_count; i++)
4121 p_s[i]->_pid = pipe_pid;
4122 }
4123 }
4124
4125 /* reset standard IO to normal */
4126 for (i = 0; i < 3; i++)
4127 {
4128 dup2(stdio[i].handle, i);
4129 fcntl(i, F_SETFD, stdio[i].flags);
4130 close(stdio[i].handle);
4131 }
4132
4133 /* if any remnant problems, clean up and bail out */
4134 if (pipe_err < 0)
4135 {
4136 for (i = 0; i < 3; i++)
4137 {
4138 close(p_fd[i].rd);
4139 close(p_fd[i].wr);
4140 }
4141 errno = EPIPE;
4142 return posix_error_with_filename(cmdstring);
4143 }
4144
4145 /* build tuple of file objects to return */
4146 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4147 PyFile_SetBufSize(p_f[0], bufsize);
4148 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4149 PyFile_SetBufSize(p_f[1], bufsize);
4150 if (n == POPEN_3)
4151 {
4152 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4153 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004154 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004155 }
4156 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004157 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004158
4159 /*
4160 * Insert the files we've created into the process dictionary
4161 * all referencing the list with the process handle and the
4162 * initial number of files (see description below in _PyPclose).
4163 * Since if _PyPclose later tried to wait on a process when all
4164 * handles weren't closed, it could create a deadlock with the
4165 * child, we spend some energy here to try to ensure that we
4166 * either insert all file handles into the dictionary or none
4167 * at all. It's a little clumsy with the various popen modes
4168 * and variable number of files involved.
4169 */
4170 if (!_PyPopenProcs)
4171 {
4172 _PyPopenProcs = PyDict_New();
4173 }
4174
4175 if (_PyPopenProcs)
4176 {
4177 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4178 int ins_rc[3];
4179
4180 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4181 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4182
4183 procObj = PyList_New(2);
4184 pidObj = PyInt_FromLong((long) pipe_pid);
4185 intObj = PyInt_FromLong((long) file_count);
4186
4187 if (procObj && pidObj && intObj)
4188 {
4189 PyList_SetItem(procObj, 0, pidObj);
4190 PyList_SetItem(procObj, 1, intObj);
4191
4192 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4193 if (fileObj[0])
4194 {
4195 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4196 fileObj[0],
4197 procObj);
4198 }
4199 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4200 if (fileObj[1])
4201 {
4202 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4203 fileObj[1],
4204 procObj);
4205 }
4206 if (file_count >= 3)
4207 {
4208 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4209 if (fileObj[2])
4210 {
4211 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4212 fileObj[2],
4213 procObj);
4214 }
4215 }
4216
4217 if (ins_rc[0] < 0 || !fileObj[0] ||
4218 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4219 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4220 {
4221 /* Something failed - remove any dictionary
4222 * entries that did make it.
4223 */
4224 if (!ins_rc[0] && fileObj[0])
4225 {
4226 PyDict_DelItem(_PyPopenProcs,
4227 fileObj[0]);
4228 }
4229 if (!ins_rc[1] && fileObj[1])
4230 {
4231 PyDict_DelItem(_PyPopenProcs,
4232 fileObj[1]);
4233 }
4234 if (!ins_rc[2] && fileObj[2])
4235 {
4236 PyDict_DelItem(_PyPopenProcs,
4237 fileObj[2]);
4238 }
4239 }
4240 }
Tim Peters11b23062003-04-23 02:39:17 +00004241
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004242 /*
4243 * Clean up our localized references for the dictionary keys
4244 * and value since PyDict_SetItem will Py_INCREF any copies
4245 * that got placed in the dictionary.
4246 */
4247 Py_XDECREF(procObj);
4248 Py_XDECREF(fileObj[0]);
4249 Py_XDECREF(fileObj[1]);
4250 Py_XDECREF(fileObj[2]);
4251 }
4252
4253 /* Child is launched. */
4254 return f;
4255}
4256
4257/*
4258 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4259 * exit code for the child process and return as a result of the close.
4260 *
4261 * This function uses the _PyPopenProcs dictionary in order to map the
4262 * input file pointer to information about the process that was
4263 * originally created by the popen* call that created the file pointer.
4264 * The dictionary uses the file pointer as a key (with one entry
4265 * inserted for each file returned by the original popen* call) and a
4266 * single list object as the value for all files from a single call.
4267 * The list object contains the Win32 process handle at [0], and a file
4268 * count at [1], which is initialized to the total number of file
4269 * handles using that list.
4270 *
4271 * This function closes whichever handle it is passed, and decrements
4272 * the file count in the dictionary for the process handle pointed to
4273 * by this file. On the last close (when the file count reaches zero),
4274 * this function will wait for the child process and then return its
4275 * exit code as the result of the close() operation. This permits the
4276 * files to be closed in any order - it is always the close() of the
4277 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004278 *
4279 * NOTE: This function is currently called with the GIL released.
4280 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004281 */
4282
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004283static int _PyPclose(FILE *file)
4284{
4285 int result;
4286 int exit_code;
4287 int pipe_pid;
4288 PyObject *procObj, *pidObj, *intObj, *fileObj;
4289 int file_count;
4290#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004291 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004292#endif
4293
4294 /* Close the file handle first, to ensure it can't block the
4295 * child from exiting if it's the last handle.
4296 */
4297 result = fclose(file);
4298
4299#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004300 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004301#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004302 if (_PyPopenProcs)
4303 {
4304 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4305 (procObj = PyDict_GetItem(_PyPopenProcs,
4306 fileObj)) != NULL &&
4307 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4308 (intObj = PyList_GetItem(procObj,1)) != NULL)
4309 {
4310 pipe_pid = (int) PyInt_AsLong(pidObj);
4311 file_count = (int) PyInt_AsLong(intObj);
4312
4313 if (file_count > 1)
4314 {
4315 /* Still other files referencing process */
4316 file_count--;
4317 PyList_SetItem(procObj,1,
4318 PyInt_FromLong((long) file_count));
4319 }
4320 else
4321 {
4322 /* Last file for this process */
4323 if (result != EOF &&
4324 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4325 {
4326 /* extract exit status */
4327 if (WIFEXITED(exit_code))
4328 {
4329 result = WEXITSTATUS(exit_code);
4330 }
4331 else
4332 {
4333 errno = EPIPE;
4334 result = -1;
4335 }
4336 }
4337 else
4338 {
4339 /* Indicate failure - this will cause the file object
4340 * to raise an I/O error and translate the last
4341 * error code from errno. We do have a problem with
4342 * last errors that overlap the normal errno table,
4343 * but that's a consistent problem with the file object.
4344 */
4345 result = -1;
4346 }
4347 }
4348
4349 /* Remove this file pointer from dictionary */
4350 PyDict_DelItem(_PyPopenProcs, fileObj);
4351
4352 if (PyDict_Size(_PyPopenProcs) == 0)
4353 {
4354 Py_DECREF(_PyPopenProcs);
4355 _PyPopenProcs = NULL;
4356 }
4357
4358 } /* if object retrieval ok */
4359
4360 Py_XDECREF(fileObj);
4361 } /* if _PyPopenProcs */
4362
4363#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004364 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004365#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004366 return result;
4367}
4368
4369#endif /* PYCC_??? */
4370
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004371#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004372
4373/*
4374 * Portable 'popen' replacement for Win32.
4375 *
4376 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4377 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004378 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004379 */
4380
4381#include <malloc.h>
4382#include <io.h>
4383#include <fcntl.h>
4384
4385/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4386#define POPEN_1 1
4387#define POPEN_2 2
4388#define POPEN_3 3
4389#define POPEN_4 4
4390
4391static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004392static int _PyPclose(FILE *file);
4393
4394/*
4395 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004396 * for use when retrieving the process exit code. See _PyPclose() below
4397 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004398 */
4399static PyObject *_PyPopenProcs = NULL;
4400
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004401
4402/* popen that works from a GUI.
4403 *
4404 * The result of this function is a pipe (file) connected to the
4405 * processes stdin or stdout, depending on the requested mode.
4406 */
4407
4408static PyObject *
4409posix_popen(PyObject *self, PyObject *args)
4410{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004411 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004412 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004413
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004414 char *cmdstring;
4415 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004416 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004417 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004418 return NULL;
4419
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004420 if (*mode == 'r')
4421 tm = _O_RDONLY;
4422 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004423 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004424 return NULL;
4425 } else
4426 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004427
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004428 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004429 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004430 return NULL;
4431 }
4432
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004433 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004434 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004435 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004436 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004437 else
4438 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4439
4440 return f;
4441}
4442
4443/* Variation on win32pipe.popen
4444 *
4445 * The result of this function is a pipe (file) connected to the
4446 * process's stdin, and a pipe connected to the process's stdout.
4447 */
4448
4449static PyObject *
4450win32_popen2(PyObject *self, PyObject *args)
4451{
4452 PyObject *f;
4453 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004454
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004455 char *cmdstring;
4456 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004457 int bufsize = -1;
4458 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004459 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004460
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 if (*mode == 't')
4462 tm = _O_TEXT;
4463 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004464 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 return NULL;
4466 } else
4467 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004468
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004469 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004470 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004471 return NULL;
4472 }
4473
4474 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004475
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004476 return f;
4477}
4478
4479/*
4480 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004481 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 * The result of this function is 3 pipes - the process's stdin,
4483 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 */
4485
4486static PyObject *
4487win32_popen3(PyObject *self, PyObject *args)
4488{
4489 PyObject *f;
4490 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004491
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004492 char *cmdstring;
4493 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004494 int bufsize = -1;
4495 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004496 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004497
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004498 if (*mode == 't')
4499 tm = _O_TEXT;
4500 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004501 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004502 return NULL;
4503 } else
4504 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004505
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004506 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004507 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004508 return NULL;
4509 }
4510
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004511 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004512
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004513 return f;
4514}
4515
4516/*
4517 * Variation on win32pipe.popen
4518 *
Tim Peters5aa91602002-01-30 05:46:57 +00004519 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004520 * and stdout+stderr combined as a single pipe.
4521 */
4522
4523static PyObject *
4524win32_popen4(PyObject *self, PyObject *args)
4525{
4526 PyObject *f;
4527 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004528
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004529 char *cmdstring;
4530 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004531 int bufsize = -1;
4532 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004533 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004534
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004535 if (*mode == 't')
4536 tm = _O_TEXT;
4537 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004538 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004539 return NULL;
4540 } else
4541 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004542
4543 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004544 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004545 return NULL;
4546 }
4547
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004548 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004549
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 return f;
4551}
4552
Mark Hammond08501372001-01-31 07:30:29 +00004553static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004554_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004555 HANDLE hStdin,
4556 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004557 HANDLE hStderr,
4558 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004559{
4560 PROCESS_INFORMATION piProcInfo;
4561 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004562 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004564 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004565 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004566 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567
4568 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004569 char *comshell;
4570
Tim Peters92e4dd82002-10-05 01:47:34 +00004571 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004573 /* x < i, so x fits into an integer */
4574 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004575
4576 /* Explicitly check if we are using COMMAND.COM. If we are
4577 * then use the w9xpopen hack.
4578 */
4579 comshell = s1 + x;
4580 while (comshell >= s1 && *comshell != '\\')
4581 --comshell;
4582 ++comshell;
4583
4584 if (GetVersion() < 0x80000000 &&
4585 _stricmp(comshell, "command.com") != 0) {
4586 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004587 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004588 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004590 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004591 }
4592 else {
4593 /*
Tim Peters402d5982001-08-27 06:37:48 +00004594 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4595 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004596 */
Mark Hammond08501372001-01-31 07:30:29 +00004597 char modulepath[_MAX_PATH];
4598 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004599 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004600 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004601 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 x = i+1;
4603 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004604 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004605 strncat(modulepath,
4606 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004607 (sizeof(modulepath)/sizeof(modulepath[0]))
4608 -strlen(modulepath));
4609 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004610 /* Eeek - file-not-found - possibly an embedding
4611 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004612 */
Tim Peters5aa91602002-01-30 05:46:57 +00004613 strncpy(modulepath,
4614 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004615 sizeof(modulepath)/sizeof(modulepath[0]));
4616 if (modulepath[strlen(modulepath)-1] != '\\')
4617 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004618 strncat(modulepath,
4619 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004620 (sizeof(modulepath)/sizeof(modulepath[0]))
4621 -strlen(modulepath));
4622 /* No where else to look - raise an easily identifiable
4623 error, rather than leaving Windows to report
4624 "file not found" - as the user is probably blissfully
4625 unaware this shim EXE is used, and it will confuse them.
4626 (well, it confused me for a while ;-)
4627 */
4628 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004629 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004630 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004631 "for popen to work with your shell "
4632 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004633 szConsoleSpawn);
4634 return FALSE;
4635 }
4636 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004637 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004638 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004639 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004640
Tim Peters92e4dd82002-10-05 01:47:34 +00004641 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004642 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004643 /* To maintain correct argument passing semantics,
4644 we pass the command-line as it stands, and allow
4645 quoting to be applied. w9xpopen.exe will then
4646 use its argv vector, and re-quote the necessary
4647 args for the ultimate child process.
4648 */
Tim Peters75cdad52001-11-28 22:07:30 +00004649 PyOS_snprintf(
4650 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004651 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004652 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004653 s1,
4654 s3,
4655 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004656 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004657 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004658 dialog:
4659 "Your program accessed mem currently in use at xxx"
4660 and a hopeful warning about the stability of your
4661 system.
4662 Cost is Ctrl+C wont kill children, but anyone
4663 who cares can have a go!
4664 */
4665 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004666 }
4667 }
4668
4669 /* Could be an else here to try cmd.exe / command.com in the path
4670 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004671 else {
Tim Peters402d5982001-08-27 06:37:48 +00004672 PyErr_SetString(PyExc_RuntimeError,
4673 "Cannot locate a COMSPEC environment variable to "
4674 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004675 return FALSE;
4676 }
Tim Peters5aa91602002-01-30 05:46:57 +00004677
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004678 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4679 siStartInfo.cb = sizeof(STARTUPINFO);
4680 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4681 siStartInfo.hStdInput = hStdin;
4682 siStartInfo.hStdOutput = hStdout;
4683 siStartInfo.hStdError = hStderr;
4684 siStartInfo.wShowWindow = SW_HIDE;
4685
4686 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004687 s2,
4688 NULL,
4689 NULL,
4690 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004691 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004692 NULL,
4693 NULL,
4694 &siStartInfo,
4695 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004696 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004697 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004698
Mark Hammondb37a3732000-08-14 04:47:33 +00004699 /* Return process handle */
4700 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004701 return TRUE;
4702 }
Tim Peters402d5982001-08-27 06:37:48 +00004703 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004704 return FALSE;
4705}
4706
4707/* The following code is based off of KB: Q190351 */
4708
4709static PyObject *
4710_PyPopen(char *cmdstring, int mode, int n)
4711{
4712 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4713 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004714 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004715
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004716 SECURITY_ATTRIBUTES saAttr;
4717 BOOL fSuccess;
4718 int fd1, fd2, fd3;
4719 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004720 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004721 PyObject *f;
4722
4723 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4724 saAttr.bInheritHandle = TRUE;
4725 saAttr.lpSecurityDescriptor = NULL;
4726
4727 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4728 return win32_error("CreatePipe", NULL);
4729
4730 /* Create new output read handle and the input write handle. Set
4731 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004732 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004733 * being created. */
4734 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004735 GetCurrentProcess(), &hChildStdinWrDup, 0,
4736 FALSE,
4737 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004738 if (!fSuccess)
4739 return win32_error("DuplicateHandle", NULL);
4740
4741 /* Close the inheritable version of ChildStdin
4742 that we're using. */
4743 CloseHandle(hChildStdinWr);
4744
4745 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4746 return win32_error("CreatePipe", NULL);
4747
4748 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004749 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4750 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004751 if (!fSuccess)
4752 return win32_error("DuplicateHandle", NULL);
4753
4754 /* Close the inheritable version of ChildStdout
4755 that we're using. */
4756 CloseHandle(hChildStdoutRd);
4757
4758 if (n != POPEN_4) {
4759 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4760 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004761 fSuccess = DuplicateHandle(GetCurrentProcess(),
4762 hChildStderrRd,
4763 GetCurrentProcess(),
4764 &hChildStderrRdDup, 0,
4765 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004766 if (!fSuccess)
4767 return win32_error("DuplicateHandle", NULL);
4768 /* Close the inheritable version of ChildStdErr that we're using. */
4769 CloseHandle(hChildStderrRd);
4770 }
Tim Peters5aa91602002-01-30 05:46:57 +00004771
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004772 switch (n) {
4773 case POPEN_1:
4774 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4775 case _O_WRONLY | _O_TEXT:
4776 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004777 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004778 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004779 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004780 PyFile_SetBufSize(f, 0);
4781 /* We don't care about these pipes anymore, so close them. */
4782 CloseHandle(hChildStdoutRdDup);
4783 CloseHandle(hChildStderrRdDup);
4784 break;
4785
4786 case _O_RDONLY | _O_TEXT:
4787 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004788 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004789 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004790 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004791 PyFile_SetBufSize(f, 0);
4792 /* We don't care about these pipes anymore, so close them. */
4793 CloseHandle(hChildStdinWrDup);
4794 CloseHandle(hChildStderrRdDup);
4795 break;
4796
4797 case _O_RDONLY | _O_BINARY:
4798 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004799 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004800 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004801 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004802 PyFile_SetBufSize(f, 0);
4803 /* We don't care about these pipes anymore, so close them. */
4804 CloseHandle(hChildStdinWrDup);
4805 CloseHandle(hChildStderrRdDup);
4806 break;
4807
4808 case _O_WRONLY | _O_BINARY:
4809 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004810 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004811 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004812 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004813 PyFile_SetBufSize(f, 0);
4814 /* We don't care about these pipes anymore, so close them. */
4815 CloseHandle(hChildStdoutRdDup);
4816 CloseHandle(hChildStderrRdDup);
4817 break;
4818 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004819 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004820 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004821
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004822 case POPEN_2:
4823 case POPEN_4:
4824 {
4825 char *m1, *m2;
4826 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004827
Tim Peters7dca21e2002-08-19 00:42:29 +00004828 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829 m1 = "r";
4830 m2 = "w";
4831 } else {
4832 m1 = "rb";
4833 m2 = "wb";
4834 }
4835
Martin v. Löwis18e16552006-02-15 17:27:45 +00004836 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004837 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004838 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004839 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004840 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004841 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004842 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004843 PyFile_SetBufSize(p2, 0);
4844
4845 if (n != 4)
4846 CloseHandle(hChildStderrRdDup);
4847
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004848 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004849 Py_XDECREF(p1);
4850 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004851 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004852 break;
4853 }
Tim Peters5aa91602002-01-30 05:46:57 +00004854
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004855 case POPEN_3:
4856 {
4857 char *m1, *m2;
4858 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004859
Tim Peters7dca21e2002-08-19 00:42:29 +00004860 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004861 m1 = "r";
4862 m2 = "w";
4863 } else {
4864 m1 = "rb";
4865 m2 = "wb";
4866 }
4867
Martin v. Löwis18e16552006-02-15 17:27:45 +00004868 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004869 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004870 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004872 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004874 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004875 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4876 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004877 PyFile_SetBufSize(p1, 0);
4878 PyFile_SetBufSize(p2, 0);
4879 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004880 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004881 Py_XDECREF(p1);
4882 Py_XDECREF(p2);
4883 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004884 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004885 break;
4886 }
4887 }
4888
4889 if (n == POPEN_4) {
4890 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004891 hChildStdinRd,
4892 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004893 hChildStdoutWr,
4894 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004895 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004896 }
4897 else {
4898 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004899 hChildStdinRd,
4900 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004901 hChildStderrWr,
4902 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004903 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004904 }
4905
Mark Hammondb37a3732000-08-14 04:47:33 +00004906 /*
4907 * Insert the files we've created into the process dictionary
4908 * all referencing the list with the process handle and the
4909 * initial number of files (see description below in _PyPclose).
4910 * Since if _PyPclose later tried to wait on a process when all
4911 * handles weren't closed, it could create a deadlock with the
4912 * child, we spend some energy here to try to ensure that we
4913 * either insert all file handles into the dictionary or none
4914 * at all. It's a little clumsy with the various popen modes
4915 * and variable number of files involved.
4916 */
4917 if (!_PyPopenProcs) {
4918 _PyPopenProcs = PyDict_New();
4919 }
4920
4921 if (_PyPopenProcs) {
4922 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4923 int ins_rc[3];
4924
4925 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4926 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4927
4928 procObj = PyList_New(2);
4929 hProcessObj = PyLong_FromVoidPtr(hProcess);
4930 intObj = PyInt_FromLong(file_count);
4931
4932 if (procObj && hProcessObj && intObj) {
4933 PyList_SetItem(procObj,0,hProcessObj);
4934 PyList_SetItem(procObj,1,intObj);
4935
4936 fileObj[0] = PyLong_FromVoidPtr(f1);
4937 if (fileObj[0]) {
4938 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4939 fileObj[0],
4940 procObj);
4941 }
4942 if (file_count >= 2) {
4943 fileObj[1] = PyLong_FromVoidPtr(f2);
4944 if (fileObj[1]) {
4945 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4946 fileObj[1],
4947 procObj);
4948 }
4949 }
4950 if (file_count >= 3) {
4951 fileObj[2] = PyLong_FromVoidPtr(f3);
4952 if (fileObj[2]) {
4953 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4954 fileObj[2],
4955 procObj);
4956 }
4957 }
4958
4959 if (ins_rc[0] < 0 || !fileObj[0] ||
4960 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4961 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4962 /* Something failed - remove any dictionary
4963 * entries that did make it.
4964 */
4965 if (!ins_rc[0] && fileObj[0]) {
4966 PyDict_DelItem(_PyPopenProcs,
4967 fileObj[0]);
4968 }
4969 if (!ins_rc[1] && fileObj[1]) {
4970 PyDict_DelItem(_PyPopenProcs,
4971 fileObj[1]);
4972 }
4973 if (!ins_rc[2] && fileObj[2]) {
4974 PyDict_DelItem(_PyPopenProcs,
4975 fileObj[2]);
4976 }
4977 }
4978 }
Tim Peters5aa91602002-01-30 05:46:57 +00004979
Mark Hammondb37a3732000-08-14 04:47:33 +00004980 /*
4981 * Clean up our localized references for the dictionary keys
4982 * and value since PyDict_SetItem will Py_INCREF any copies
4983 * that got placed in the dictionary.
4984 */
4985 Py_XDECREF(procObj);
4986 Py_XDECREF(fileObj[0]);
4987 Py_XDECREF(fileObj[1]);
4988 Py_XDECREF(fileObj[2]);
4989 }
4990
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004991 /* Child is launched. Close the parents copy of those pipe
4992 * handles that only the child should have open. You need to
4993 * make sure that no handles to the write end of the output pipe
4994 * are maintained in this process or else the pipe will not close
4995 * when the child process exits and the ReadFile will hang. */
4996
4997 if (!CloseHandle(hChildStdinRd))
4998 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004999
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005000 if (!CloseHandle(hChildStdoutWr))
5001 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005002
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005003 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5004 return win32_error("CloseHandle", NULL);
5005
5006 return f;
5007}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005008
5009/*
5010 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5011 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005012 *
5013 * This function uses the _PyPopenProcs dictionary in order to map the
5014 * input file pointer to information about the process that was
5015 * originally created by the popen* call that created the file pointer.
5016 * The dictionary uses the file pointer as a key (with one entry
5017 * inserted for each file returned by the original popen* call) and a
5018 * single list object as the value for all files from a single call.
5019 * The list object contains the Win32 process handle at [0], and a file
5020 * count at [1], which is initialized to the total number of file
5021 * handles using that list.
5022 *
5023 * This function closes whichever handle it is passed, and decrements
5024 * the file count in the dictionary for the process handle pointed to
5025 * by this file. On the last close (when the file count reaches zero),
5026 * this function will wait for the child process and then return its
5027 * exit code as the result of the close() operation. This permits the
5028 * files to be closed in any order - it is always the close() of the
5029 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005030 *
5031 * NOTE: This function is currently called with the GIL released.
5032 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005033 */
Tim Peters736aa322000-09-01 06:51:24 +00005034
Fredrik Lundh56055a42000-07-23 19:47:12 +00005035static int _PyPclose(FILE *file)
5036{
Fredrik Lundh20318932000-07-26 17:29:12 +00005037 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005038 DWORD exit_code;
5039 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005040 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5041 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005042#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005043 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005044#endif
5045
Fredrik Lundh20318932000-07-26 17:29:12 +00005046 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005047 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005048 */
5049 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005050#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005051 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005052#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005053 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005054 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5055 (procObj = PyDict_GetItem(_PyPopenProcs,
5056 fileObj)) != NULL &&
5057 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5058 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5059
5060 hProcess = PyLong_AsVoidPtr(hProcessObj);
5061 file_count = PyInt_AsLong(intObj);
5062
5063 if (file_count > 1) {
5064 /* Still other files referencing process */
5065 file_count--;
5066 PyList_SetItem(procObj,1,
5067 PyInt_FromLong(file_count));
5068 } else {
5069 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005070 if (result != EOF &&
5071 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5072 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005073 /* Possible truncation here in 16-bit environments, but
5074 * real exit codes are just the lower byte in any event.
5075 */
5076 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005077 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005078 /* Indicate failure - this will cause the file object
5079 * to raise an I/O error and translate the last Win32
5080 * error code from errno. We do have a problem with
5081 * last errors that overlap the normal errno table,
5082 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005083 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005084 if (result != EOF) {
5085 /* If the error wasn't from the fclose(), then
5086 * set errno for the file object error handling.
5087 */
5088 errno = GetLastError();
5089 }
5090 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005091 }
5092
5093 /* Free up the native handle at this point */
5094 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005095 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005096
Mark Hammondb37a3732000-08-14 04:47:33 +00005097 /* Remove this file pointer from dictionary */
5098 PyDict_DelItem(_PyPopenProcs, fileObj);
5099
5100 if (PyDict_Size(_PyPopenProcs) == 0) {
5101 Py_DECREF(_PyPopenProcs);
5102 _PyPopenProcs = NULL;
5103 }
5104
5105 } /* if object retrieval ok */
5106
5107 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005108 } /* if _PyPopenProcs */
5109
Tim Peters736aa322000-09-01 06:51:24 +00005110#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005111 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005112#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005113 return result;
5114}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005115
5116#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005118posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005119{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005120 char *name;
5121 char *mode = "r";
5122 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005123 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005124 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005125 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005126 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005127 /* Strip mode of binary or text modifiers */
5128 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5129 mode = "r";
5130 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5131 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005132 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005133 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005134 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005135 if (fp == NULL)
5136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005138 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005139 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005140 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005141}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005142
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005143#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005144#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005146
Guido van Rossumb6775db1994-08-01 11:34:53 +00005147#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005149"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150Set the current process's user id.");
5151
Barry Warsaw53699e91996-12-10 23:23:01 +00005152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005153posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005154{
5155 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005156 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005157 return NULL;
5158 if (setuid(uid) < 0)
5159 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005160 Py_INCREF(Py_None);
5161 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005162}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005163#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005165
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005166#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005168"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005169Set the current process's effective user id.");
5170
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005171static PyObject *
5172posix_seteuid (PyObject *self, PyObject *args)
5173{
5174 int euid;
5175 if (!PyArg_ParseTuple(args, "i", &euid)) {
5176 return NULL;
5177 } else if (seteuid(euid) < 0) {
5178 return posix_error();
5179 } else {
5180 Py_INCREF(Py_None);
5181 return Py_None;
5182 }
5183}
5184#endif /* HAVE_SETEUID */
5185
5186#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005187PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005188"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005189Set the current process's effective group id.");
5190
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005191static PyObject *
5192posix_setegid (PyObject *self, PyObject *args)
5193{
5194 int egid;
5195 if (!PyArg_ParseTuple(args, "i", &egid)) {
5196 return NULL;
5197 } else if (setegid(egid) < 0) {
5198 return posix_error();
5199 } else {
5200 Py_INCREF(Py_None);
5201 return Py_None;
5202 }
5203}
5204#endif /* HAVE_SETEGID */
5205
5206#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005207PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005208"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005209Set the current process's real and effective user ids.");
5210
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005211static PyObject *
5212posix_setreuid (PyObject *self, PyObject *args)
5213{
5214 int ruid, euid;
5215 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5216 return NULL;
5217 } else if (setreuid(ruid, euid) < 0) {
5218 return posix_error();
5219 } else {
5220 Py_INCREF(Py_None);
5221 return Py_None;
5222 }
5223}
5224#endif /* HAVE_SETREUID */
5225
5226#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005227PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005228"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229Set the current process's real and effective group ids.");
5230
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005231static PyObject *
5232posix_setregid (PyObject *self, PyObject *args)
5233{
5234 int rgid, egid;
5235 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5236 return NULL;
5237 } else if (setregid(rgid, egid) < 0) {
5238 return posix_error();
5239 } else {
5240 Py_INCREF(Py_None);
5241 return Py_None;
5242 }
5243}
5244#endif /* HAVE_SETREGID */
5245
Guido van Rossumb6775db1994-08-01 11:34:53 +00005246#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005247PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005248"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005249Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005250
Barry Warsaw53699e91996-12-10 23:23:01 +00005251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005252posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005253{
5254 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005255 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005256 return NULL;
5257 if (setgid(gid) < 0)
5258 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005259 Py_INCREF(Py_None);
5260 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005261}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005262#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005263
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005264#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005266"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005267Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005268
5269static PyObject *
5270posix_setgroups(PyObject *self, PyObject *args)
5271{
5272 PyObject *groups;
5273 int i, len;
5274 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005275
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005276 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5277 return NULL;
5278 if (!PySequence_Check(groups)) {
5279 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5280 return NULL;
5281 }
5282 len = PySequence_Size(groups);
5283 if (len > MAX_GROUPS) {
5284 PyErr_SetString(PyExc_ValueError, "too many groups");
5285 return NULL;
5286 }
5287 for(i = 0; i < len; i++) {
5288 PyObject *elem;
5289 elem = PySequence_GetItem(groups, i);
5290 if (!elem)
5291 return NULL;
5292 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005293 if (!PyLong_Check(elem)) {
5294 PyErr_SetString(PyExc_TypeError,
5295 "groups must be integers");
5296 Py_DECREF(elem);
5297 return NULL;
5298 } else {
5299 unsigned long x = PyLong_AsUnsignedLong(elem);
5300 if (PyErr_Occurred()) {
5301 PyErr_SetString(PyExc_TypeError,
5302 "group id too big");
5303 Py_DECREF(elem);
5304 return NULL;
5305 }
5306 grouplist[i] = x;
5307 /* read back the value to see if it fitted in gid_t */
5308 if (grouplist[i] != x) {
5309 PyErr_SetString(PyExc_TypeError,
5310 "group id too big");
5311 Py_DECREF(elem);
5312 return NULL;
5313 }
5314 }
5315 } else {
5316 long x = PyInt_AsLong(elem);
5317 grouplist[i] = x;
5318 if (grouplist[i] != x) {
5319 PyErr_SetString(PyExc_TypeError,
5320 "group id too big");
5321 Py_DECREF(elem);
5322 return NULL;
5323 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005324 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005325 Py_DECREF(elem);
5326 }
5327
5328 if (setgroups(len, grouplist) < 0)
5329 return posix_error();
5330 Py_INCREF(Py_None);
5331 return Py_None;
5332}
5333#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005334
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005335#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005336static PyObject *
5337wait_helper(int pid, int status, struct rusage *ru)
5338{
5339 PyObject *result;
5340 static PyObject *struct_rusage;
5341
5342 if (pid == -1)
5343 return posix_error();
5344
5345 if (struct_rusage == NULL) {
5346 PyObject *m = PyImport_ImportModule("resource");
5347 if (m == NULL)
5348 return NULL;
5349 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5350 Py_DECREF(m);
5351 if (struct_rusage == NULL)
5352 return NULL;
5353 }
5354
5355 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5356 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5357 if (!result)
5358 return NULL;
5359
5360#ifndef doubletime
5361#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5362#endif
5363
5364 PyStructSequence_SET_ITEM(result, 0,
5365 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5366 PyStructSequence_SET_ITEM(result, 1,
5367 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5368#define SET_INT(result, index, value)\
5369 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5370 SET_INT(result, 2, ru->ru_maxrss);
5371 SET_INT(result, 3, ru->ru_ixrss);
5372 SET_INT(result, 4, ru->ru_idrss);
5373 SET_INT(result, 5, ru->ru_isrss);
5374 SET_INT(result, 6, ru->ru_minflt);
5375 SET_INT(result, 7, ru->ru_majflt);
5376 SET_INT(result, 8, ru->ru_nswap);
5377 SET_INT(result, 9, ru->ru_inblock);
5378 SET_INT(result, 10, ru->ru_oublock);
5379 SET_INT(result, 11, ru->ru_msgsnd);
5380 SET_INT(result, 12, ru->ru_msgrcv);
5381 SET_INT(result, 13, ru->ru_nsignals);
5382 SET_INT(result, 14, ru->ru_nvcsw);
5383 SET_INT(result, 15, ru->ru_nivcsw);
5384#undef SET_INT
5385
5386 if (PyErr_Occurred()) {
5387 Py_DECREF(result);
5388 return NULL;
5389 }
5390
Neal Norwitz9b00a562006-03-20 08:47:12 +00005391 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005392}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005393#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005394
5395#ifdef HAVE_WAIT3
5396PyDoc_STRVAR(posix_wait3__doc__,
5397"wait3(options) -> (pid, status, rusage)\n\n\
5398Wait for completion of a child process.");
5399
5400static PyObject *
5401posix_wait3(PyObject *self, PyObject *args)
5402{
5403 int pid, options;
5404 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005405 WAIT_TYPE status;
5406 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005407
5408 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5409 return NULL;
5410
5411 Py_BEGIN_ALLOW_THREADS
5412 pid = wait3(&status, options, &ru);
5413 Py_END_ALLOW_THREADS
5414
Neal Norwitzd5a37542006-03-20 06:48:34 +00005415 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005416}
5417#endif /* HAVE_WAIT3 */
5418
5419#ifdef HAVE_WAIT4
5420PyDoc_STRVAR(posix_wait4__doc__,
5421"wait4(pid, options) -> (pid, status, rusage)\n\n\
5422Wait for completion of a given child process.");
5423
5424static PyObject *
5425posix_wait4(PyObject *self, PyObject *args)
5426{
5427 int pid, options;
5428 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005429 WAIT_TYPE status;
5430 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005431
5432 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5433 return NULL;
5434
5435 Py_BEGIN_ALLOW_THREADS
5436 pid = wait4(pid, &status, options, &ru);
5437 Py_END_ALLOW_THREADS
5438
Neal Norwitzd5a37542006-03-20 06:48:34 +00005439 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005440}
5441#endif /* HAVE_WAIT4 */
5442
Guido van Rossumb6775db1994-08-01 11:34:53 +00005443#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005445"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005446Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005447
Barry Warsaw53699e91996-12-10 23:23:01 +00005448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005449posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005450{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005451 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005452 WAIT_TYPE status;
5453 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005454
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005455 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005456 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005457 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005458 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005459 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005460 if (pid == -1)
5461 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005462
5463 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005464}
5465
Tim Petersab034fa2002-02-01 11:27:43 +00005466#elif defined(HAVE_CWAIT)
5467
5468/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005470"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005471"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005472
5473static PyObject *
5474posix_waitpid(PyObject *self, PyObject *args)
5475{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005476 intptr_t pid;
5477 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005478
5479 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5480 return NULL;
5481 Py_BEGIN_ALLOW_THREADS
5482 pid = _cwait(&status, pid, options);
5483 Py_END_ALLOW_THREADS
5484 if (pid == -1)
5485 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005486
5487 /* shift the status left a byte so this is more like the POSIX waitpid */
5488 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005489}
5490#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005491
Guido van Rossumad0ee831995-03-01 10:34:45 +00005492#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005494"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005496
Barry Warsaw53699e91996-12-10 23:23:01 +00005497static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005498posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005499{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005500 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005501 WAIT_TYPE status;
5502 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005503
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005504 Py_BEGIN_ALLOW_THREADS
5505 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005506 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005507 if (pid == -1)
5508 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005509
5510 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005511}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005512#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005513
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Barry Warsaw53699e91996-12-10 23:23:01 +00005519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005520posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005521{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005522#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005523 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005524#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005525#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005526 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005527#else
5528 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5529#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005530#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005531}
5532
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005533
Guido van Rossumb6775db1994-08-01 11:34:53 +00005534#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005535PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005536"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005537Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005538
Barry Warsaw53699e91996-12-10 23:23:01 +00005539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005540posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005541{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005542 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005543 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005544 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005545 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005546 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005547 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005548 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005549 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005550 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005551 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005552 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005553}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005554#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005556
Guido van Rossumb6775db1994-08-01 11:34:53 +00005557#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005558PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005559"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005560Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005561
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005563posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005564{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005565 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005566}
5567#endif /* HAVE_SYMLINK */
5568
5569
5570#ifdef HAVE_TIMES
5571#ifndef HZ
5572#define HZ 60 /* Universal constant :-) */
5573#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005574
Guido van Rossumd48f2521997-12-05 22:19:34 +00005575#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5576static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005577system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005578{
5579 ULONG value = 0;
5580
5581 Py_BEGIN_ALLOW_THREADS
5582 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5583 Py_END_ALLOW_THREADS
5584
5585 return value;
5586}
5587
5588static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005589posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005590{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005591 /* Currently Only Uptime is Provided -- Others Later */
5592 return Py_BuildValue("ddddd",
5593 (double)0 /* t.tms_utime / HZ */,
5594 (double)0 /* t.tms_stime / HZ */,
5595 (double)0 /* t.tms_cutime / HZ */,
5596 (double)0 /* t.tms_cstime / HZ */,
5597 (double)system_uptime() / 1000);
5598}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005599#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005600static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005601posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005602{
5603 struct tms t;
5604 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005605 errno = 0;
5606 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005607 if (c == (clock_t) -1)
5608 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005609 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005610 (double)t.tms_utime / HZ,
5611 (double)t.tms_stime / HZ,
5612 (double)t.tms_cutime / HZ,
5613 (double)t.tms_cstime / HZ,
5614 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005615}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005616#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005617#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005618
5619
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005620#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005621#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005622static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005623posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005624{
5625 FILETIME create, exit, kernel, user;
5626 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005627 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005628 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5629 /* The fields of a FILETIME structure are the hi and lo part
5630 of a 64-bit value expressed in 100 nanosecond units.
5631 1e7 is one second in such units; 1e-7 the inverse.
5632 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5633 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005634 return Py_BuildValue(
5635 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005636 (double)(kernel.dwHighDateTime*429.4967296 +
5637 kernel.dwLowDateTime*1e-7),
5638 (double)(user.dwHighDateTime*429.4967296 +
5639 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005640 (double)0,
5641 (double)0,
5642 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005643}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005644#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005645
5646#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005648"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005650#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005651
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005652
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005653#ifdef HAVE_GETSID
5654PyDoc_STRVAR(posix_getsid__doc__,
5655"getsid(pid) -> sid\n\n\
5656Call the system call getsid().");
5657
5658static PyObject *
5659posix_getsid(PyObject *self, PyObject *args)
5660{
5661 int pid, sid;
5662 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5663 return NULL;
5664 sid = getsid(pid);
5665 if (sid < 0)
5666 return posix_error();
5667 return PyInt_FromLong((long)sid);
5668}
5669#endif /* HAVE_GETSID */
5670
5671
Guido van Rossumb6775db1994-08-01 11:34:53 +00005672#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005673PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005674"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005675Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005676
Barry Warsaw53699e91996-12-10 23:23:01 +00005677static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005678posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005679{
Guido van Rossum687dd131993-05-17 08:34:16 +00005680 if (setsid() < 0)
5681 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005682 Py_INCREF(Py_None);
5683 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005684}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005685#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005686
Guido van Rossumb6775db1994-08-01 11:34:53 +00005687#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005691
Barry Warsaw53699e91996-12-10 23:23:01 +00005692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005694{
5695 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005696 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005697 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005698 if (setpgid(pid, pgrp) < 0)
5699 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005700 Py_INCREF(Py_None);
5701 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005702}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005703#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005704
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005705
Guido van Rossumb6775db1994-08-01 11:34:53 +00005706#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005708"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005710
Barry Warsaw53699e91996-12-10 23:23:01 +00005711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005712posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005713{
5714 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005715 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005716 return NULL;
5717 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005718 if (pgid < 0)
5719 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005720 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005721}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005722#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005724
Guido van Rossumb6775db1994-08-01 11:34:53 +00005725#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005727"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005728Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005729
Barry Warsaw53699e91996-12-10 23:23:01 +00005730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005731posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005732{
5733 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005735 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005736 if (tcsetpgrp(fd, pgid) < 0)
5737 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005738 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005739 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005740}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005741#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005742
Guido van Rossum687dd131993-05-17 08:34:16 +00005743/* Functions acting on file descriptors */
5744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005746"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005748
Barry Warsaw53699e91996-12-10 23:23:01 +00005749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005750posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005751{
Mark Hammondef8b6542001-05-13 08:04:26 +00005752 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005753 int flag;
5754 int mode = 0777;
5755 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005756
5757#ifdef MS_WINDOWS
5758 if (unicode_file_names()) {
5759 PyUnicodeObject *po;
5760 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5761 Py_BEGIN_ALLOW_THREADS
5762 /* PyUnicode_AS_UNICODE OK without thread
5763 lock as it is a simple dereference. */
5764 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5765 Py_END_ALLOW_THREADS
5766 if (fd < 0)
5767 return posix_error();
5768 return PyInt_FromLong((long)fd);
5769 }
5770 /* Drop the argument parsing error as narrow strings
5771 are also valid. */
5772 PyErr_Clear();
5773 }
5774#endif
5775
Tim Peters5aa91602002-01-30 05:46:57 +00005776 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005777 Py_FileSystemDefaultEncoding, &file,
5778 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005779 return NULL;
5780
Barry Warsaw53699e91996-12-10 23:23:01 +00005781 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005782 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005783 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005784 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005785 return posix_error_with_allocated_filename(file);
5786 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005787 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005788}
5789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005792"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005794
Barry Warsaw53699e91996-12-10 23:23:01 +00005795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005796posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005797{
5798 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005799 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005800 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005801 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005802 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005803 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005804 if (res < 0)
5805 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005806 Py_INCREF(Py_None);
5807 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005808}
5809
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005811PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005812"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005813Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005814
Barry Warsaw53699e91996-12-10 23:23:01 +00005815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005816posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005817{
5818 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005819 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005820 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005821 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005822 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005823 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005824 if (fd < 0)
5825 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005826 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005827}
5828
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005829
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005831"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005833
Barry Warsaw53699e91996-12-10 23:23:01 +00005834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005835posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005836{
5837 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005838 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005839 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005840 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005841 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005842 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005843 if (res < 0)
5844 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005845 Py_INCREF(Py_None);
5846 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005847}
5848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005850PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005851"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005852Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005853
Barry Warsaw53699e91996-12-10 23:23:01 +00005854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005855posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005856{
5857 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005858#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005859 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005860#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005861 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005862#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005863 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005864 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005865 return NULL;
5866#ifdef SEEK_SET
5867 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5868 switch (how) {
5869 case 0: how = SEEK_SET; break;
5870 case 1: how = SEEK_CUR; break;
5871 case 2: how = SEEK_END; break;
5872 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005873#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005874
5875#if !defined(HAVE_LARGEFILE_SUPPORT)
5876 pos = PyInt_AsLong(posobj);
5877#else
5878 pos = PyLong_Check(posobj) ?
5879 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5880#endif
5881 if (PyErr_Occurred())
5882 return NULL;
5883
Barry Warsaw53699e91996-12-10 23:23:01 +00005884 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005885#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005886 res = _lseeki64(fd, pos, how);
5887#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005888 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005889#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005890 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005891 if (res < 0)
5892 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005893
5894#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005895 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005896#else
5897 return PyLong_FromLongLong(res);
5898#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005899}
5900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005901
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005903"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005904Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005905
Barry Warsaw53699e91996-12-10 23:23:01 +00005906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005907posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005908{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005909 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005910 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005911 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005912 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005913 if (size < 0) {
5914 errno = EINVAL;
5915 return posix_error();
5916 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005917 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005918 if (buffer == NULL)
5919 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005920 Py_BEGIN_ALLOW_THREADS
5921 n = read(fd, PyString_AsString(buffer), size);
5922 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005923 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005924 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005925 return posix_error();
5926 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005927 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005928 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005929 return buffer;
5930}
5931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005932
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005933PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005934"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005935Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005936
Barry Warsaw53699e91996-12-10 23:23:01 +00005937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005938posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005939{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005940 int fd;
5941 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005942 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005943
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005944 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005945 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005946 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005947 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005948 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005949 if (size < 0)
5950 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005951 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005952}
5953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005956"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005957Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005958
Barry Warsaw53699e91996-12-10 23:23:01 +00005959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005960posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005961{
5962 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005963 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005964 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005965 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005966 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005967#ifdef __VMS
5968 /* on OpenVMS we must ensure that all bytes are written to the file */
5969 fsync(fd);
5970#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005971 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005972 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005973 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005974 if (res != 0) {
5975#ifdef MS_WINDOWS
5976 return win32_error("fstat", NULL);
5977#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005978 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005979#endif
5980 }
Tim Peters5aa91602002-01-30 05:46:57 +00005981
Martin v. Löwis14694662006-02-03 12:54:16 +00005982 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005983}
5984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005985
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005986PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005987"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005989
Barry Warsaw53699e91996-12-10 23:23:01 +00005990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005991posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005992{
Guido van Rossum687dd131993-05-17 08:34:16 +00005993 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005994 char *mode = "r";
5995 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005996 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005997 PyObject *f;
5998 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005999 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006000
Thomas Heller1f043e22002-11-07 16:00:59 +00006001 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6002 PyErr_Format(PyExc_ValueError,
6003 "invalid file mode '%s'", mode);
6004 return NULL;
6005 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006006 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006007#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006008 if (mode[0] == 'a') {
6009 /* try to make sure the O_APPEND flag is set */
6010 int flags;
6011 flags = fcntl(fd, F_GETFL);
6012 if (flags != -1)
6013 fcntl(fd, F_SETFL, flags | O_APPEND);
6014 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006015 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006016 /* restore old mode if fdopen failed */
6017 fcntl(fd, F_SETFL, flags);
6018 } else {
6019 fp = fdopen(fd, mode);
6020 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006021#else
6022 fp = fdopen(fd, mode);
6023#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006024 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006025 if (fp == NULL)
6026 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006027 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006028 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006029 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006030 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006031}
6032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006034"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006035Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006037
6038static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006039posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006040{
6041 int fd;
6042 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6043 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006044 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006045}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006046
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006047#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006049"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006051
Barry Warsaw53699e91996-12-10 23:23:01 +00006052static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006053posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006054{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006055#if defined(PYOS_OS2)
6056 HFILE read, write;
6057 APIRET rc;
6058
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006059 Py_BEGIN_ALLOW_THREADS
6060 rc = DosCreatePipe( &read, &write, 4096);
6061 Py_END_ALLOW_THREADS
6062 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006063 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006064
6065 return Py_BuildValue("(ii)", read, write);
6066#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006067#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006068 int fds[2];
6069 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006070 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006071 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006072 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006073 if (res != 0)
6074 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006075 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006076#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006077 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006078 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006079 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006080 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006081 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006082 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006083 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006084 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006085 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6086 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006087 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006088#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006089#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006090}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006091#endif /* HAVE_PIPE */
6092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006093
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006094#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006096"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006098
Barry Warsaw53699e91996-12-10 23:23:01 +00006099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006100posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006101{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006102 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006103 int mode = 0666;
6104 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006105 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006106 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006107 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006108 res = mkfifo(filename, mode);
6109 Py_END_ALLOW_THREADS
6110 if (res < 0)
6111 return posix_error();
6112 Py_INCREF(Py_None);
6113 return Py_None;
6114}
6115#endif
6116
6117
Neal Norwitz11690112002-07-30 01:08:28 +00006118#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006119PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006120"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006121Create a filesystem node (file, device special file or named pipe)\n\
6122named filename. mode specifies both the permissions to use and the\n\
6123type of node to be created, being combined (bitwise OR) with one of\n\
6124S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006125device defines the newly created device special file (probably using\n\
6126os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006127
6128
6129static PyObject *
6130posix_mknod(PyObject *self, PyObject *args)
6131{
6132 char *filename;
6133 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006134 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006135 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006136 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006137 return NULL;
6138 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006139 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006140 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006141 if (res < 0)
6142 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006143 Py_INCREF(Py_None);
6144 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006145}
6146#endif
6147
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006148#ifdef HAVE_DEVICE_MACROS
6149PyDoc_STRVAR(posix_major__doc__,
6150"major(device) -> major number\n\
6151Extracts a device major number from a raw device number.");
6152
6153static PyObject *
6154posix_major(PyObject *self, PyObject *args)
6155{
6156 int device;
6157 if (!PyArg_ParseTuple(args, "i:major", &device))
6158 return NULL;
6159 return PyInt_FromLong((long)major(device));
6160}
6161
6162PyDoc_STRVAR(posix_minor__doc__,
6163"minor(device) -> minor number\n\
6164Extracts a device minor number from a raw device number.");
6165
6166static PyObject *
6167posix_minor(PyObject *self, PyObject *args)
6168{
6169 int device;
6170 if (!PyArg_ParseTuple(args, "i:minor", &device))
6171 return NULL;
6172 return PyInt_FromLong((long)minor(device));
6173}
6174
6175PyDoc_STRVAR(posix_makedev__doc__,
6176"makedev(major, minor) -> device number\n\
6177Composes a raw device number from the major and minor device numbers.");
6178
6179static PyObject *
6180posix_makedev(PyObject *self, PyObject *args)
6181{
6182 int major, minor;
6183 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6184 return NULL;
6185 return PyInt_FromLong((long)makedev(major, minor));
6186}
6187#endif /* device macros */
6188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006189
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006190#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006192"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006193Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006194
Barry Warsaw53699e91996-12-10 23:23:01 +00006195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006196posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006197{
6198 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006199 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006200 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006201 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006202
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006203 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006204 return NULL;
6205
6206#if !defined(HAVE_LARGEFILE_SUPPORT)
6207 length = PyInt_AsLong(lenobj);
6208#else
6209 length = PyLong_Check(lenobj) ?
6210 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6211#endif
6212 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006213 return NULL;
6214
Barry Warsaw53699e91996-12-10 23:23:01 +00006215 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006216 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006217 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006218 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006219 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006220 return NULL;
6221 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006222 Py_INCREF(Py_None);
6223 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006224}
6225#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006226
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006227#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006228PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006229"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006230Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006231
Fred Drake762e2061999-08-26 17:23:54 +00006232/* Save putenv() parameters as values here, so we can collect them when they
6233 * get re-set with another call for the same key. */
6234static PyObject *posix_putenv_garbage;
6235
Tim Peters5aa91602002-01-30 05:46:57 +00006236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006237posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006238{
6239 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006240 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006241 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006242 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006243
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006245 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006246
6247#if defined(PYOS_OS2)
6248 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6249 APIRET rc;
6250
Guido van Rossumd48f2521997-12-05 22:19:34 +00006251 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6252 if (rc != NO_ERROR)
6253 return os2_error(rc);
6254
6255 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6256 APIRET rc;
6257
Guido van Rossumd48f2521997-12-05 22:19:34 +00006258 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6259 if (rc != NO_ERROR)
6260 return os2_error(rc);
6261 } else {
6262#endif
6263
Fred Drake762e2061999-08-26 17:23:54 +00006264 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006265 len = strlen(s1) + strlen(s2) + 2;
6266 /* len includes space for a trailing \0; the size arg to
6267 PyString_FromStringAndSize does not count that */
6268 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006269 if (newstr == NULL)
6270 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006271 newenv = PyString_AS_STRING(newstr);
6272 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6273 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006274 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006275 posix_error();
6276 return NULL;
6277 }
Fred Drake762e2061999-08-26 17:23:54 +00006278 /* Install the first arg and newstr in posix_putenv_garbage;
6279 * this will cause previous value to be collected. This has to
6280 * happen after the real putenv() call because the old value
6281 * was still accessible until then. */
6282 if (PyDict_SetItem(posix_putenv_garbage,
6283 PyTuple_GET_ITEM(args, 0), newstr)) {
6284 /* really not much we can do; just leak */
6285 PyErr_Clear();
6286 }
6287 else {
6288 Py_DECREF(newstr);
6289 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006290
6291#if defined(PYOS_OS2)
6292 }
6293#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006294 Py_INCREF(Py_None);
6295 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006296}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006297#endif /* putenv */
6298
Guido van Rossumc524d952001-10-19 01:31:59 +00006299#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006302Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006303
6304static PyObject *
6305posix_unsetenv(PyObject *self, PyObject *args)
6306{
6307 char *s1;
6308
6309 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6310 return NULL;
6311
6312 unsetenv(s1);
6313
6314 /* Remove the key from posix_putenv_garbage;
6315 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006316 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006317 * old value was still accessible until then.
6318 */
6319 if (PyDict_DelItem(posix_putenv_garbage,
6320 PyTuple_GET_ITEM(args, 0))) {
6321 /* really not much we can do; just leak */
6322 PyErr_Clear();
6323 }
6324
6325 Py_INCREF(Py_None);
6326 return Py_None;
6327}
6328#endif /* unsetenv */
6329
Guido van Rossumb6a47161997-09-15 22:54:34 +00006330#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006332"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006333Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006334
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006336posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006337{
6338 int code;
6339 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006341 return NULL;
6342 message = strerror(code);
6343 if (message == NULL) {
6344 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006345 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006346 return NULL;
6347 }
6348 return PyString_FromString(message);
6349}
6350#endif /* strerror */
6351
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006352
Guido van Rossumc9641791998-08-04 15:26:23 +00006353#ifdef HAVE_SYS_WAIT_H
6354
Fred Drake106c1a02002-04-23 15:58:02 +00006355#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006356PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006357"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006358Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006359
6360static PyObject *
6361posix_WCOREDUMP(PyObject *self, PyObject *args)
6362{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006363 WAIT_TYPE status;
6364 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006365
Neal Norwitzd5a37542006-03-20 06:48:34 +00006366 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006367 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006368
6369 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006370}
6371#endif /* WCOREDUMP */
6372
6373#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006374PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006375"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006376Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006378
6379static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006380posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006381{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006382 WAIT_TYPE status;
6383 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006384
Neal Norwitzd5a37542006-03-20 06:48:34 +00006385 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006386 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006387
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006388 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006389}
6390#endif /* WIFCONTINUED */
6391
Guido van Rossumc9641791998-08-04 15:26:23 +00006392#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006393PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006394"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006395Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006396
6397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006398posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006399{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006400 WAIT_TYPE status;
6401 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006402
Neal Norwitzd5a37542006-03-20 06:48:34 +00006403 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006404 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006405
Fred Drake106c1a02002-04-23 15:58:02 +00006406 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006407}
6408#endif /* WIFSTOPPED */
6409
6410#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006414
6415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006417{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006418 WAIT_TYPE status;
6419 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006420
Neal Norwitzd5a37542006-03-20 06:48:34 +00006421 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006422 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006423
Fred Drake106c1a02002-04-23 15:58:02 +00006424 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006425}
6426#endif /* WIFSIGNALED */
6427
6428#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006429PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006430"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006431Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006432system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006433
6434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006435posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006436{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006437 WAIT_TYPE status;
6438 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006439
Neal Norwitzd5a37542006-03-20 06:48:34 +00006440 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006441 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006442
Fred Drake106c1a02002-04-23 15:58:02 +00006443 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006444}
6445#endif /* WIFEXITED */
6446
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006447#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006448PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006449"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006450Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006451
6452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006453posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006454{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006455 WAIT_TYPE status;
6456 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006457
Neal Norwitzd5a37542006-03-20 06:48:34 +00006458 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006459 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006460
Guido van Rossumc9641791998-08-04 15:26:23 +00006461 return Py_BuildValue("i", WEXITSTATUS(status));
6462}
6463#endif /* WEXITSTATUS */
6464
6465#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006466PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006467"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006468Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006470
6471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006472posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006473{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006474 WAIT_TYPE status;
6475 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006476
Neal Norwitzd5a37542006-03-20 06:48:34 +00006477 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006478 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006479
Guido van Rossumc9641791998-08-04 15:26:23 +00006480 return Py_BuildValue("i", WTERMSIG(status));
6481}
6482#endif /* WTERMSIG */
6483
6484#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006485PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006486"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006487Return the signal that stopped the process that provided\n\
6488the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006489
6490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006491posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006492{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006493 WAIT_TYPE status;
6494 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006495
Neal Norwitzd5a37542006-03-20 06:48:34 +00006496 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006497 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006498
Guido van Rossumc9641791998-08-04 15:26:23 +00006499 return Py_BuildValue("i", WSTOPSIG(status));
6500}
6501#endif /* WSTOPSIG */
6502
6503#endif /* HAVE_SYS_WAIT_H */
6504
6505
Guido van Rossum94f6f721999-01-06 18:42:14 +00006506#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006507#ifdef _SCO_DS
6508/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6509 needed definitions in sys/statvfs.h */
6510#define _SVID3
6511#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006512#include <sys/statvfs.h>
6513
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006514static PyObject*
6515_pystatvfs_fromstructstatvfs(struct statvfs st) {
6516 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6517 if (v == NULL)
6518 return NULL;
6519
6520#if !defined(HAVE_LARGEFILE_SUPPORT)
6521 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6522 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6523 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6524 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6525 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6526 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6527 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6528 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6529 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6530 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6531#else
6532 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6533 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006534 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006535 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006536 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006537 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006538 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006539 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006540 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006541 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006542 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006543 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006544 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006545 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006546 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6547 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6548#endif
6549
6550 return v;
6551}
6552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006554"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006555Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006556
6557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006558posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006559{
6560 int fd, res;
6561 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006562
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006563 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006564 return NULL;
6565 Py_BEGIN_ALLOW_THREADS
6566 res = fstatvfs(fd, &st);
6567 Py_END_ALLOW_THREADS
6568 if (res != 0)
6569 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006570
6571 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006572}
6573#endif /* HAVE_FSTATVFS */
6574
6575
6576#if defined(HAVE_STATVFS)
6577#include <sys/statvfs.h>
6578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006579PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006580"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006581Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006582
6583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006584posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006585{
6586 char *path;
6587 int res;
6588 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006589 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006590 return NULL;
6591 Py_BEGIN_ALLOW_THREADS
6592 res = statvfs(path, &st);
6593 Py_END_ALLOW_THREADS
6594 if (res != 0)
6595 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006596
6597 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006598}
6599#endif /* HAVE_STATVFS */
6600
6601
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006602#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006603PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006604"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006605Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006606The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006608
6609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006610posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006611{
6612 PyObject *result = NULL;
6613 char *dir = NULL;
6614 char *pfx = NULL;
6615 char *name;
6616
6617 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6618 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006619
6620 if (PyErr_Warn(PyExc_RuntimeWarning,
6621 "tempnam is a potential security risk to your program") < 0)
6622 return NULL;
6623
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006624#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006625 name = _tempnam(dir, pfx);
6626#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006627 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006628#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006629 if (name == NULL)
6630 return PyErr_NoMemory();
6631 result = PyString_FromString(name);
6632 free(name);
6633 return result;
6634}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006635#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006636
6637
6638#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006640"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006642
6643static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006644posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006645{
6646 FILE *fp;
6647
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006648 fp = tmpfile();
6649 if (fp == NULL)
6650 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006651 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006652}
6653#endif
6654
6655
6656#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006657PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006658"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006659Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006660
6661static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006662posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006663{
6664 char buffer[L_tmpnam];
6665 char *name;
6666
Skip Montanaro95618b52001-08-18 18:52:10 +00006667 if (PyErr_Warn(PyExc_RuntimeWarning,
6668 "tmpnam is a potential security risk to your program") < 0)
6669 return NULL;
6670
Greg Wardb48bc172000-03-01 21:51:56 +00006671#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006672 name = tmpnam_r(buffer);
6673#else
6674 name = tmpnam(buffer);
6675#endif
6676 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006677 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006678#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006679 "unexpected NULL from tmpnam_r"
6680#else
6681 "unexpected NULL from tmpnam"
6682#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006683 );
6684 PyErr_SetObject(PyExc_OSError, err);
6685 Py_XDECREF(err);
6686 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006687 }
6688 return PyString_FromString(buffer);
6689}
6690#endif
6691
6692
Fred Drakec9680921999-12-13 16:37:25 +00006693/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6694 * It maps strings representing configuration variable names to
6695 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006696 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006697 * rarely-used constants. There are three separate tables that use
6698 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006699 *
6700 * This code is always included, even if none of the interfaces that
6701 * need it are included. The #if hackery needed to avoid it would be
6702 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006703 */
6704struct constdef {
6705 char *name;
6706 long value;
6707};
6708
Fred Drake12c6e2d1999-12-14 21:25:03 +00006709static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006710conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6711 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006712{
6713 if (PyInt_Check(arg)) {
6714 *valuep = PyInt_AS_LONG(arg);
6715 return 1;
6716 }
6717 if (PyString_Check(arg)) {
6718 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006719 size_t lo = 0;
6720 size_t mid;
6721 size_t hi = tablesize;
6722 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006723 char *confname = PyString_AS_STRING(arg);
6724 while (lo < hi) {
6725 mid = (lo + hi) / 2;
6726 cmp = strcmp(confname, table[mid].name);
6727 if (cmp < 0)
6728 hi = mid;
6729 else if (cmp > 0)
6730 lo = mid + 1;
6731 else {
6732 *valuep = table[mid].value;
6733 return 1;
6734 }
6735 }
6736 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6737 }
6738 else
6739 PyErr_SetString(PyExc_TypeError,
6740 "configuration names must be strings or integers");
6741 return 0;
6742}
6743
6744
6745#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6746static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006747#ifdef _PC_ABI_AIO_XFER_MAX
6748 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6749#endif
6750#ifdef _PC_ABI_ASYNC_IO
6751 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6752#endif
Fred Drakec9680921999-12-13 16:37:25 +00006753#ifdef _PC_ASYNC_IO
6754 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6755#endif
6756#ifdef _PC_CHOWN_RESTRICTED
6757 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6758#endif
6759#ifdef _PC_FILESIZEBITS
6760 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6761#endif
6762#ifdef _PC_LAST
6763 {"PC_LAST", _PC_LAST},
6764#endif
6765#ifdef _PC_LINK_MAX
6766 {"PC_LINK_MAX", _PC_LINK_MAX},
6767#endif
6768#ifdef _PC_MAX_CANON
6769 {"PC_MAX_CANON", _PC_MAX_CANON},
6770#endif
6771#ifdef _PC_MAX_INPUT
6772 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6773#endif
6774#ifdef _PC_NAME_MAX
6775 {"PC_NAME_MAX", _PC_NAME_MAX},
6776#endif
6777#ifdef _PC_NO_TRUNC
6778 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6779#endif
6780#ifdef _PC_PATH_MAX
6781 {"PC_PATH_MAX", _PC_PATH_MAX},
6782#endif
6783#ifdef _PC_PIPE_BUF
6784 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6785#endif
6786#ifdef _PC_PRIO_IO
6787 {"PC_PRIO_IO", _PC_PRIO_IO},
6788#endif
6789#ifdef _PC_SOCK_MAXBUF
6790 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6791#endif
6792#ifdef _PC_SYNC_IO
6793 {"PC_SYNC_IO", _PC_SYNC_IO},
6794#endif
6795#ifdef _PC_VDISABLE
6796 {"PC_VDISABLE", _PC_VDISABLE},
6797#endif
6798};
6799
Fred Drakec9680921999-12-13 16:37:25 +00006800static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006801conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006802{
6803 return conv_confname(arg, valuep, posix_constants_pathconf,
6804 sizeof(posix_constants_pathconf)
6805 / sizeof(struct constdef));
6806}
6807#endif
6808
6809#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006810PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006811"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006812Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006813If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006814
6815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006816posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006817{
6818 PyObject *result = NULL;
6819 int name, fd;
6820
Fred Drake12c6e2d1999-12-14 21:25:03 +00006821 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6822 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006823 long limit;
6824
6825 errno = 0;
6826 limit = fpathconf(fd, name);
6827 if (limit == -1 && errno != 0)
6828 posix_error();
6829 else
6830 result = PyInt_FromLong(limit);
6831 }
6832 return result;
6833}
6834#endif
6835
6836
6837#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006838PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006839"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006840Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006841If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006842
6843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006844posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006845{
6846 PyObject *result = NULL;
6847 int name;
6848 char *path;
6849
6850 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6851 conv_path_confname, &name)) {
6852 long limit;
6853
6854 errno = 0;
6855 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006856 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006857 if (errno == EINVAL)
6858 /* could be a path or name problem */
6859 posix_error();
6860 else
6861 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006862 }
Fred Drakec9680921999-12-13 16:37:25 +00006863 else
6864 result = PyInt_FromLong(limit);
6865 }
6866 return result;
6867}
6868#endif
6869
6870#ifdef HAVE_CONFSTR
6871static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006872#ifdef _CS_ARCHITECTURE
6873 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6874#endif
6875#ifdef _CS_HOSTNAME
6876 {"CS_HOSTNAME", _CS_HOSTNAME},
6877#endif
6878#ifdef _CS_HW_PROVIDER
6879 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6880#endif
6881#ifdef _CS_HW_SERIAL
6882 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6883#endif
6884#ifdef _CS_INITTAB_NAME
6885 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6886#endif
Fred Drakec9680921999-12-13 16:37:25 +00006887#ifdef _CS_LFS64_CFLAGS
6888 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6889#endif
6890#ifdef _CS_LFS64_LDFLAGS
6891 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6892#endif
6893#ifdef _CS_LFS64_LIBS
6894 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6895#endif
6896#ifdef _CS_LFS64_LINTFLAGS
6897 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6898#endif
6899#ifdef _CS_LFS_CFLAGS
6900 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6901#endif
6902#ifdef _CS_LFS_LDFLAGS
6903 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6904#endif
6905#ifdef _CS_LFS_LIBS
6906 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6907#endif
6908#ifdef _CS_LFS_LINTFLAGS
6909 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6910#endif
Fred Draked86ed291999-12-15 15:34:33 +00006911#ifdef _CS_MACHINE
6912 {"CS_MACHINE", _CS_MACHINE},
6913#endif
Fred Drakec9680921999-12-13 16:37:25 +00006914#ifdef _CS_PATH
6915 {"CS_PATH", _CS_PATH},
6916#endif
Fred Draked86ed291999-12-15 15:34:33 +00006917#ifdef _CS_RELEASE
6918 {"CS_RELEASE", _CS_RELEASE},
6919#endif
6920#ifdef _CS_SRPC_DOMAIN
6921 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6922#endif
6923#ifdef _CS_SYSNAME
6924 {"CS_SYSNAME", _CS_SYSNAME},
6925#endif
6926#ifdef _CS_VERSION
6927 {"CS_VERSION", _CS_VERSION},
6928#endif
Fred Drakec9680921999-12-13 16:37:25 +00006929#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6930 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6931#endif
6932#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6933 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6934#endif
6935#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6936 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6937#endif
6938#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6939 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6940#endif
6941#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6942 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6943#endif
6944#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6945 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6946#endif
6947#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6948 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6949#endif
6950#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6951 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6952#endif
6953#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6954 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6955#endif
6956#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6957 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6958#endif
6959#ifdef _CS_XBS5_LP64_OFF64_LIBS
6960 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6961#endif
6962#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6963 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6964#endif
6965#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6966 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6967#endif
6968#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6969 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6970#endif
6971#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6972 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6973#endif
6974#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6975 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6976#endif
Fred Draked86ed291999-12-15 15:34:33 +00006977#ifdef _MIPS_CS_AVAIL_PROCESSORS
6978 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6979#endif
6980#ifdef _MIPS_CS_BASE
6981 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6982#endif
6983#ifdef _MIPS_CS_HOSTID
6984 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6985#endif
6986#ifdef _MIPS_CS_HW_NAME
6987 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6988#endif
6989#ifdef _MIPS_CS_NUM_PROCESSORS
6990 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6991#endif
6992#ifdef _MIPS_CS_OSREL_MAJ
6993 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6994#endif
6995#ifdef _MIPS_CS_OSREL_MIN
6996 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6997#endif
6998#ifdef _MIPS_CS_OSREL_PATCH
6999 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7000#endif
7001#ifdef _MIPS_CS_OS_NAME
7002 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7003#endif
7004#ifdef _MIPS_CS_OS_PROVIDER
7005 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7006#endif
7007#ifdef _MIPS_CS_PROCESSORS
7008 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7009#endif
7010#ifdef _MIPS_CS_SERIAL
7011 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7012#endif
7013#ifdef _MIPS_CS_VENDOR
7014 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7015#endif
Fred Drakec9680921999-12-13 16:37:25 +00007016};
7017
7018static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007019conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007020{
7021 return conv_confname(arg, valuep, posix_constants_confstr,
7022 sizeof(posix_constants_confstr)
7023 / sizeof(struct constdef));
7024}
7025
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007026PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007027"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007028Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007029
7030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007031posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007032{
7033 PyObject *result = NULL;
7034 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007035 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007036
7037 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007038 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007039
Fred Drakec9680921999-12-13 16:37:25 +00007040 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007041 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007042 if (len == 0) {
7043 if (errno) {
7044 posix_error();
7045 }
7046 else {
7047 result = Py_None;
7048 Py_INCREF(Py_None);
7049 }
Fred Drakec9680921999-12-13 16:37:25 +00007050 }
7051 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007052 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00007053 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007054 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00007055 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007056 }
7057 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00007058 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007059 }
7060 }
7061 return result;
7062}
7063#endif
7064
7065
7066#ifdef HAVE_SYSCONF
7067static struct constdef posix_constants_sysconf[] = {
7068#ifdef _SC_2_CHAR_TERM
7069 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7070#endif
7071#ifdef _SC_2_C_BIND
7072 {"SC_2_C_BIND", _SC_2_C_BIND},
7073#endif
7074#ifdef _SC_2_C_DEV
7075 {"SC_2_C_DEV", _SC_2_C_DEV},
7076#endif
7077#ifdef _SC_2_C_VERSION
7078 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7079#endif
7080#ifdef _SC_2_FORT_DEV
7081 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7082#endif
7083#ifdef _SC_2_FORT_RUN
7084 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7085#endif
7086#ifdef _SC_2_LOCALEDEF
7087 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7088#endif
7089#ifdef _SC_2_SW_DEV
7090 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7091#endif
7092#ifdef _SC_2_UPE
7093 {"SC_2_UPE", _SC_2_UPE},
7094#endif
7095#ifdef _SC_2_VERSION
7096 {"SC_2_VERSION", _SC_2_VERSION},
7097#endif
Fred Draked86ed291999-12-15 15:34:33 +00007098#ifdef _SC_ABI_ASYNCHRONOUS_IO
7099 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7100#endif
7101#ifdef _SC_ACL
7102 {"SC_ACL", _SC_ACL},
7103#endif
Fred Drakec9680921999-12-13 16:37:25 +00007104#ifdef _SC_AIO_LISTIO_MAX
7105 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7106#endif
Fred Drakec9680921999-12-13 16:37:25 +00007107#ifdef _SC_AIO_MAX
7108 {"SC_AIO_MAX", _SC_AIO_MAX},
7109#endif
7110#ifdef _SC_AIO_PRIO_DELTA_MAX
7111 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7112#endif
7113#ifdef _SC_ARG_MAX
7114 {"SC_ARG_MAX", _SC_ARG_MAX},
7115#endif
7116#ifdef _SC_ASYNCHRONOUS_IO
7117 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7118#endif
7119#ifdef _SC_ATEXIT_MAX
7120 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7121#endif
Fred Draked86ed291999-12-15 15:34:33 +00007122#ifdef _SC_AUDIT
7123 {"SC_AUDIT", _SC_AUDIT},
7124#endif
Fred Drakec9680921999-12-13 16:37:25 +00007125#ifdef _SC_AVPHYS_PAGES
7126 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7127#endif
7128#ifdef _SC_BC_BASE_MAX
7129 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7130#endif
7131#ifdef _SC_BC_DIM_MAX
7132 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7133#endif
7134#ifdef _SC_BC_SCALE_MAX
7135 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7136#endif
7137#ifdef _SC_BC_STRING_MAX
7138 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7139#endif
Fred Draked86ed291999-12-15 15:34:33 +00007140#ifdef _SC_CAP
7141 {"SC_CAP", _SC_CAP},
7142#endif
Fred Drakec9680921999-12-13 16:37:25 +00007143#ifdef _SC_CHARCLASS_NAME_MAX
7144 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7145#endif
7146#ifdef _SC_CHAR_BIT
7147 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7148#endif
7149#ifdef _SC_CHAR_MAX
7150 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7151#endif
7152#ifdef _SC_CHAR_MIN
7153 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7154#endif
7155#ifdef _SC_CHILD_MAX
7156 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7157#endif
7158#ifdef _SC_CLK_TCK
7159 {"SC_CLK_TCK", _SC_CLK_TCK},
7160#endif
7161#ifdef _SC_COHER_BLKSZ
7162 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7163#endif
7164#ifdef _SC_COLL_WEIGHTS_MAX
7165 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7166#endif
7167#ifdef _SC_DCACHE_ASSOC
7168 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7169#endif
7170#ifdef _SC_DCACHE_BLKSZ
7171 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7172#endif
7173#ifdef _SC_DCACHE_LINESZ
7174 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7175#endif
7176#ifdef _SC_DCACHE_SZ
7177 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7178#endif
7179#ifdef _SC_DCACHE_TBLKSZ
7180 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7181#endif
7182#ifdef _SC_DELAYTIMER_MAX
7183 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7184#endif
7185#ifdef _SC_EQUIV_CLASS_MAX
7186 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7187#endif
7188#ifdef _SC_EXPR_NEST_MAX
7189 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7190#endif
7191#ifdef _SC_FSYNC
7192 {"SC_FSYNC", _SC_FSYNC},
7193#endif
7194#ifdef _SC_GETGR_R_SIZE_MAX
7195 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7196#endif
7197#ifdef _SC_GETPW_R_SIZE_MAX
7198 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7199#endif
7200#ifdef _SC_ICACHE_ASSOC
7201 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7202#endif
7203#ifdef _SC_ICACHE_BLKSZ
7204 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7205#endif
7206#ifdef _SC_ICACHE_LINESZ
7207 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7208#endif
7209#ifdef _SC_ICACHE_SZ
7210 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7211#endif
Fred Draked86ed291999-12-15 15:34:33 +00007212#ifdef _SC_INF
7213 {"SC_INF", _SC_INF},
7214#endif
Fred Drakec9680921999-12-13 16:37:25 +00007215#ifdef _SC_INT_MAX
7216 {"SC_INT_MAX", _SC_INT_MAX},
7217#endif
7218#ifdef _SC_INT_MIN
7219 {"SC_INT_MIN", _SC_INT_MIN},
7220#endif
7221#ifdef _SC_IOV_MAX
7222 {"SC_IOV_MAX", _SC_IOV_MAX},
7223#endif
Fred Draked86ed291999-12-15 15:34:33 +00007224#ifdef _SC_IP_SECOPTS
7225 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7226#endif
Fred Drakec9680921999-12-13 16:37:25 +00007227#ifdef _SC_JOB_CONTROL
7228 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7229#endif
Fred Draked86ed291999-12-15 15:34:33 +00007230#ifdef _SC_KERN_POINTERS
7231 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7232#endif
7233#ifdef _SC_KERN_SIM
7234 {"SC_KERN_SIM", _SC_KERN_SIM},
7235#endif
Fred Drakec9680921999-12-13 16:37:25 +00007236#ifdef _SC_LINE_MAX
7237 {"SC_LINE_MAX", _SC_LINE_MAX},
7238#endif
7239#ifdef _SC_LOGIN_NAME_MAX
7240 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7241#endif
7242#ifdef _SC_LOGNAME_MAX
7243 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7244#endif
7245#ifdef _SC_LONG_BIT
7246 {"SC_LONG_BIT", _SC_LONG_BIT},
7247#endif
Fred Draked86ed291999-12-15 15:34:33 +00007248#ifdef _SC_MAC
7249 {"SC_MAC", _SC_MAC},
7250#endif
Fred Drakec9680921999-12-13 16:37:25 +00007251#ifdef _SC_MAPPED_FILES
7252 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7253#endif
7254#ifdef _SC_MAXPID
7255 {"SC_MAXPID", _SC_MAXPID},
7256#endif
7257#ifdef _SC_MB_LEN_MAX
7258 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7259#endif
7260#ifdef _SC_MEMLOCK
7261 {"SC_MEMLOCK", _SC_MEMLOCK},
7262#endif
7263#ifdef _SC_MEMLOCK_RANGE
7264 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7265#endif
7266#ifdef _SC_MEMORY_PROTECTION
7267 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7268#endif
7269#ifdef _SC_MESSAGE_PASSING
7270 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7271#endif
Fred Draked86ed291999-12-15 15:34:33 +00007272#ifdef _SC_MMAP_FIXED_ALIGNMENT
7273 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7274#endif
Fred Drakec9680921999-12-13 16:37:25 +00007275#ifdef _SC_MQ_OPEN_MAX
7276 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7277#endif
7278#ifdef _SC_MQ_PRIO_MAX
7279 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7280#endif
Fred Draked86ed291999-12-15 15:34:33 +00007281#ifdef _SC_NACLS_MAX
7282 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7283#endif
Fred Drakec9680921999-12-13 16:37:25 +00007284#ifdef _SC_NGROUPS_MAX
7285 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7286#endif
7287#ifdef _SC_NL_ARGMAX
7288 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7289#endif
7290#ifdef _SC_NL_LANGMAX
7291 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7292#endif
7293#ifdef _SC_NL_MSGMAX
7294 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7295#endif
7296#ifdef _SC_NL_NMAX
7297 {"SC_NL_NMAX", _SC_NL_NMAX},
7298#endif
7299#ifdef _SC_NL_SETMAX
7300 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7301#endif
7302#ifdef _SC_NL_TEXTMAX
7303 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7304#endif
7305#ifdef _SC_NPROCESSORS_CONF
7306 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7307#endif
7308#ifdef _SC_NPROCESSORS_ONLN
7309 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7310#endif
Fred Draked86ed291999-12-15 15:34:33 +00007311#ifdef _SC_NPROC_CONF
7312 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7313#endif
7314#ifdef _SC_NPROC_ONLN
7315 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7316#endif
Fred Drakec9680921999-12-13 16:37:25 +00007317#ifdef _SC_NZERO
7318 {"SC_NZERO", _SC_NZERO},
7319#endif
7320#ifdef _SC_OPEN_MAX
7321 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7322#endif
7323#ifdef _SC_PAGESIZE
7324 {"SC_PAGESIZE", _SC_PAGESIZE},
7325#endif
7326#ifdef _SC_PAGE_SIZE
7327 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7328#endif
7329#ifdef _SC_PASS_MAX
7330 {"SC_PASS_MAX", _SC_PASS_MAX},
7331#endif
7332#ifdef _SC_PHYS_PAGES
7333 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7334#endif
7335#ifdef _SC_PII
7336 {"SC_PII", _SC_PII},
7337#endif
7338#ifdef _SC_PII_INTERNET
7339 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7340#endif
7341#ifdef _SC_PII_INTERNET_DGRAM
7342 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7343#endif
7344#ifdef _SC_PII_INTERNET_STREAM
7345 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7346#endif
7347#ifdef _SC_PII_OSI
7348 {"SC_PII_OSI", _SC_PII_OSI},
7349#endif
7350#ifdef _SC_PII_OSI_CLTS
7351 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7352#endif
7353#ifdef _SC_PII_OSI_COTS
7354 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7355#endif
7356#ifdef _SC_PII_OSI_M
7357 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7358#endif
7359#ifdef _SC_PII_SOCKET
7360 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7361#endif
7362#ifdef _SC_PII_XTI
7363 {"SC_PII_XTI", _SC_PII_XTI},
7364#endif
7365#ifdef _SC_POLL
7366 {"SC_POLL", _SC_POLL},
7367#endif
7368#ifdef _SC_PRIORITIZED_IO
7369 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7370#endif
7371#ifdef _SC_PRIORITY_SCHEDULING
7372 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7373#endif
7374#ifdef _SC_REALTIME_SIGNALS
7375 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7376#endif
7377#ifdef _SC_RE_DUP_MAX
7378 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7379#endif
7380#ifdef _SC_RTSIG_MAX
7381 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7382#endif
7383#ifdef _SC_SAVED_IDS
7384 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7385#endif
7386#ifdef _SC_SCHAR_MAX
7387 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7388#endif
7389#ifdef _SC_SCHAR_MIN
7390 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7391#endif
7392#ifdef _SC_SELECT
7393 {"SC_SELECT", _SC_SELECT},
7394#endif
7395#ifdef _SC_SEMAPHORES
7396 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7397#endif
7398#ifdef _SC_SEM_NSEMS_MAX
7399 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7400#endif
7401#ifdef _SC_SEM_VALUE_MAX
7402 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7403#endif
7404#ifdef _SC_SHARED_MEMORY_OBJECTS
7405 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7406#endif
7407#ifdef _SC_SHRT_MAX
7408 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7409#endif
7410#ifdef _SC_SHRT_MIN
7411 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7412#endif
7413#ifdef _SC_SIGQUEUE_MAX
7414 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7415#endif
7416#ifdef _SC_SIGRT_MAX
7417 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7418#endif
7419#ifdef _SC_SIGRT_MIN
7420 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7421#endif
Fred Draked86ed291999-12-15 15:34:33 +00007422#ifdef _SC_SOFTPOWER
7423 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7424#endif
Fred Drakec9680921999-12-13 16:37:25 +00007425#ifdef _SC_SPLIT_CACHE
7426 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7427#endif
7428#ifdef _SC_SSIZE_MAX
7429 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7430#endif
7431#ifdef _SC_STACK_PROT
7432 {"SC_STACK_PROT", _SC_STACK_PROT},
7433#endif
7434#ifdef _SC_STREAM_MAX
7435 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7436#endif
7437#ifdef _SC_SYNCHRONIZED_IO
7438 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7439#endif
7440#ifdef _SC_THREADS
7441 {"SC_THREADS", _SC_THREADS},
7442#endif
7443#ifdef _SC_THREAD_ATTR_STACKADDR
7444 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7445#endif
7446#ifdef _SC_THREAD_ATTR_STACKSIZE
7447 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7448#endif
7449#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7450 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7451#endif
7452#ifdef _SC_THREAD_KEYS_MAX
7453 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7454#endif
7455#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7456 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7457#endif
7458#ifdef _SC_THREAD_PRIO_INHERIT
7459 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7460#endif
7461#ifdef _SC_THREAD_PRIO_PROTECT
7462 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7463#endif
7464#ifdef _SC_THREAD_PROCESS_SHARED
7465 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7466#endif
7467#ifdef _SC_THREAD_SAFE_FUNCTIONS
7468 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7469#endif
7470#ifdef _SC_THREAD_STACK_MIN
7471 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7472#endif
7473#ifdef _SC_THREAD_THREADS_MAX
7474 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7475#endif
7476#ifdef _SC_TIMERS
7477 {"SC_TIMERS", _SC_TIMERS},
7478#endif
7479#ifdef _SC_TIMER_MAX
7480 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7481#endif
7482#ifdef _SC_TTY_NAME_MAX
7483 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7484#endif
7485#ifdef _SC_TZNAME_MAX
7486 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7487#endif
7488#ifdef _SC_T_IOV_MAX
7489 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7490#endif
7491#ifdef _SC_UCHAR_MAX
7492 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7493#endif
7494#ifdef _SC_UINT_MAX
7495 {"SC_UINT_MAX", _SC_UINT_MAX},
7496#endif
7497#ifdef _SC_UIO_MAXIOV
7498 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7499#endif
7500#ifdef _SC_ULONG_MAX
7501 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7502#endif
7503#ifdef _SC_USHRT_MAX
7504 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7505#endif
7506#ifdef _SC_VERSION
7507 {"SC_VERSION", _SC_VERSION},
7508#endif
7509#ifdef _SC_WORD_BIT
7510 {"SC_WORD_BIT", _SC_WORD_BIT},
7511#endif
7512#ifdef _SC_XBS5_ILP32_OFF32
7513 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7514#endif
7515#ifdef _SC_XBS5_ILP32_OFFBIG
7516 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7517#endif
7518#ifdef _SC_XBS5_LP64_OFF64
7519 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7520#endif
7521#ifdef _SC_XBS5_LPBIG_OFFBIG
7522 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7523#endif
7524#ifdef _SC_XOPEN_CRYPT
7525 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7526#endif
7527#ifdef _SC_XOPEN_ENH_I18N
7528 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7529#endif
7530#ifdef _SC_XOPEN_LEGACY
7531 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7532#endif
7533#ifdef _SC_XOPEN_REALTIME
7534 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7535#endif
7536#ifdef _SC_XOPEN_REALTIME_THREADS
7537 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7538#endif
7539#ifdef _SC_XOPEN_SHM
7540 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7541#endif
7542#ifdef _SC_XOPEN_UNIX
7543 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7544#endif
7545#ifdef _SC_XOPEN_VERSION
7546 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7547#endif
7548#ifdef _SC_XOPEN_XCU_VERSION
7549 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7550#endif
7551#ifdef _SC_XOPEN_XPG2
7552 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7553#endif
7554#ifdef _SC_XOPEN_XPG3
7555 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7556#endif
7557#ifdef _SC_XOPEN_XPG4
7558 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7559#endif
7560};
7561
7562static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007563conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007564{
7565 return conv_confname(arg, valuep, posix_constants_sysconf,
7566 sizeof(posix_constants_sysconf)
7567 / sizeof(struct constdef));
7568}
7569
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007570PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007571"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007572Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007573
7574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007575posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007576{
7577 PyObject *result = NULL;
7578 int name;
7579
7580 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7581 int value;
7582
7583 errno = 0;
7584 value = sysconf(name);
7585 if (value == -1 && errno != 0)
7586 posix_error();
7587 else
7588 result = PyInt_FromLong(value);
7589 }
7590 return result;
7591}
7592#endif
7593
7594
Fred Drakebec628d1999-12-15 18:31:10 +00007595/* This code is used to ensure that the tables of configuration value names
7596 * are in sorted order as required by conv_confname(), and also to build the
7597 * the exported dictionaries that are used to publish information about the
7598 * names available on the host platform.
7599 *
7600 * Sorting the table at runtime ensures that the table is properly ordered
7601 * when used, even for platforms we're not able to test on. It also makes
7602 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007603 */
Fred Drakebec628d1999-12-15 18:31:10 +00007604
7605static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007606cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007607{
7608 const struct constdef *c1 =
7609 (const struct constdef *) v1;
7610 const struct constdef *c2 =
7611 (const struct constdef *) v2;
7612
7613 return strcmp(c1->name, c2->name);
7614}
7615
7616static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007617setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007618 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007619{
Fred Drakebec628d1999-12-15 18:31:10 +00007620 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007621 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007622
7623 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7624 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007625 if (d == NULL)
7626 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007627
Barry Warsaw3155db32000-04-13 15:20:40 +00007628 for (i=0; i < tablesize; ++i) {
7629 PyObject *o = PyInt_FromLong(table[i].value);
7630 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7631 Py_XDECREF(o);
7632 Py_DECREF(d);
7633 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007634 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007635 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007636 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007637 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007638}
7639
Fred Drakebec628d1999-12-15 18:31:10 +00007640/* Return -1 on failure, 0 on success. */
7641static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007642setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007643{
7644#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007645 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007646 sizeof(posix_constants_pathconf)
7647 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007648 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007649 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007650#endif
7651#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007652 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007653 sizeof(posix_constants_confstr)
7654 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007655 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007656 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007657#endif
7658#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007659 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007660 sizeof(posix_constants_sysconf)
7661 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007662 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007663 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007664#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007665 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007666}
Fred Draked86ed291999-12-15 15:34:33 +00007667
7668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007669PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007670"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007671Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007672in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007673
7674static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007675posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007676{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007677 abort();
7678 /*NOTREACHED*/
7679 Py_FatalError("abort() called from Python code didn't abort!");
7680 return NULL;
7681}
Fred Drakebec628d1999-12-15 18:31:10 +00007682
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007683#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007684PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007685"startfile(filepath [, operation]) - Start a file with its associated\n\
7686application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007687\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007688When \"operation\" is not specified or \"open\", this acts like\n\
7689double-clicking the file in Explorer, or giving the file name as an\n\
7690argument to the DOS \"start\" command: the file is opened with whatever\n\
7691application (if any) its extension is associated.\n\
7692When another \"operation\" is given, it specifies what should be done with\n\
7693the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007694\n\
7695startfile returns as soon as the associated application is launched.\n\
7696There is no option to wait for the application to close, and no way\n\
7697to retrieve the application's exit status.\n\
7698\n\
7699The filepath is relative to the current directory. If you want to use\n\
7700an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007701the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007702
7703static PyObject *
7704win32_startfile(PyObject *self, PyObject *args)
7705{
7706 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007707 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007708 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007709#ifdef Py_WIN_WIDE_FILENAMES
7710 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007711 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007712 if (!PyArg_ParseTuple(args, "U|s:startfile",
7713 &unipath, &operation)) {
7714 PyErr_Clear();
7715 goto normal;
7716 }
7717
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007718
7719 if (operation) {
7720 woperation = PyUnicode_DecodeASCII(operation,
7721 strlen(operation), NULL);
7722 if (!woperation) {
7723 PyErr_Clear();
7724 operation = NULL;
7725 goto normal;
7726 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007727 }
7728
7729 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007730 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007731 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007732 NULL, NULL, SW_SHOWNORMAL);
7733 Py_END_ALLOW_THREADS
7734
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007735 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007736 if (rc <= (HINSTANCE)32) {
7737 PyObject *errval = win32_error_unicode("startfile",
7738 PyUnicode_AS_UNICODE(unipath));
7739 return errval;
7740 }
7741 Py_INCREF(Py_None);
7742 return Py_None;
7743 }
7744#endif
7745
7746normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007747 if (!PyArg_ParseTuple(args, "et|s:startfile",
7748 Py_FileSystemDefaultEncoding, &filepath,
7749 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007750 return NULL;
7751 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007752 rc = ShellExecute((HWND)0, operation, filepath,
7753 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007754 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007755 if (rc <= (HINSTANCE)32) {
7756 PyObject *errval = win32_error("startfile", filepath);
7757 PyMem_Free(filepath);
7758 return errval;
7759 }
7760 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007761 Py_INCREF(Py_None);
7762 return Py_None;
7763}
7764#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007765
Martin v. Löwis438b5342002-12-27 10:16:42 +00007766#ifdef HAVE_GETLOADAVG
7767PyDoc_STRVAR(posix_getloadavg__doc__,
7768"getloadavg() -> (float, float, float)\n\n\
7769Return the number of processes in the system run queue averaged over\n\
7770the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7771was unobtainable");
7772
7773static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007774posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007775{
7776 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007777 if (getloadavg(loadavg, 3)!=3) {
7778 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7779 return NULL;
7780 } else
7781 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7782}
7783#endif
7784
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007785#ifdef MS_WINDOWS
7786
7787PyDoc_STRVAR(win32_urandom__doc__,
7788"urandom(n) -> str\n\n\
7789Return a string of n random bytes suitable for cryptographic use.");
7790
7791typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7792 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7793 DWORD dwFlags );
7794typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7795 BYTE *pbBuffer );
7796
7797static CRYPTGENRANDOM pCryptGenRandom = NULL;
7798static HCRYPTPROV hCryptProv = 0;
7799
Tim Peters4ad82172004-08-30 17:02:04 +00007800static PyObject*
7801win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007802{
Tim Petersd3115382004-08-30 17:36:46 +00007803 int howMany;
7804 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007805
Tim Peters4ad82172004-08-30 17:02:04 +00007806 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007807 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007808 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007809 if (howMany < 0)
7810 return PyErr_Format(PyExc_ValueError,
7811 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007812
Tim Peters4ad82172004-08-30 17:02:04 +00007813 if (hCryptProv == 0) {
7814 HINSTANCE hAdvAPI32 = NULL;
7815 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007816
Tim Peters4ad82172004-08-30 17:02:04 +00007817 /* Obtain handle to the DLL containing CryptoAPI
7818 This should not fail */
7819 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7820 if(hAdvAPI32 == NULL)
7821 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007822
Tim Peters4ad82172004-08-30 17:02:04 +00007823 /* Obtain pointers to the CryptoAPI functions
7824 This will fail on some early versions of Win95 */
7825 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7826 hAdvAPI32,
7827 "CryptAcquireContextA");
7828 if (pCryptAcquireContext == NULL)
7829 return PyErr_Format(PyExc_NotImplementedError,
7830 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007831
Tim Peters4ad82172004-08-30 17:02:04 +00007832 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7833 hAdvAPI32, "CryptGenRandom");
7834 if (pCryptAcquireContext == NULL)
7835 return PyErr_Format(PyExc_NotImplementedError,
7836 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007837
Tim Peters4ad82172004-08-30 17:02:04 +00007838 /* Acquire context */
7839 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7840 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7841 return win32_error("CryptAcquireContext", NULL);
7842 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007843
Tim Peters4ad82172004-08-30 17:02:04 +00007844 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007845 result = PyString_FromStringAndSize(NULL, howMany);
7846 if (result != NULL) {
7847 /* Get random data */
7848 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7849 PyString_AS_STRING(result))) {
7850 Py_DECREF(result);
7851 return win32_error("CryptGenRandom", NULL);
7852 }
Tim Peters4ad82172004-08-30 17:02:04 +00007853 }
Tim Petersd3115382004-08-30 17:36:46 +00007854 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007855}
7856#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007857
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007858static PyMethodDef posix_methods[] = {
7859 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7860#ifdef HAVE_TTYNAME
7861 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7862#endif
7863 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7864 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007865#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007866 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007867#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007868#ifdef HAVE_LCHOWN
7869 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7870#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007871#ifdef HAVE_CHROOT
7872 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7873#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007874#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007875 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007876#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007877#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007878 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007879#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007880 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007881#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007882#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007883#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007884 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007885#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007886 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7887 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7888 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007889#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007890 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007891#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007893 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007894#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007895 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7896 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7897 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007898 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007899#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007900 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007901#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007902#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007903 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007904#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007905 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007906#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007907 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007908#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007909 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7910 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7911 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007912#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007913 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007914#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007915 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007917 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7918 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007919#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007920#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007921 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7922 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007923#if defined(PYOS_OS2)
7924 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7925 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7926#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007927#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007928#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007929 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007930#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007931#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007932 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007933#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007934#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007935 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007936#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007937#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007938 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007939#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007940#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007941 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007942#endif /* HAVE_GETEGID */
7943#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007944 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007945#endif /* HAVE_GETEUID */
7946#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007947 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007948#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007949#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007950 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007951#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007952 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007953#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007954 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007955#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007956#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007957 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007958#endif /* HAVE_GETPPID */
7959#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007960 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007961#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007962#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007963 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007964#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007965#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007966 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007967#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007968#ifdef HAVE_KILLPG
7969 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7970#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007971#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007972 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007973#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007974#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007975 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007976#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007977 {"popen2", win32_popen2, METH_VARARGS},
7978 {"popen3", win32_popen3, METH_VARARGS},
7979 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007980 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007981#else
7982#if defined(PYOS_OS2) && defined(PYCC_GCC)
7983 {"popen2", os2emx_popen2, METH_VARARGS},
7984 {"popen3", os2emx_popen3, METH_VARARGS},
7985 {"popen4", os2emx_popen4, METH_VARARGS},
7986#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007987#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007988#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007989#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007990 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007991#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007992#ifdef HAVE_SETEUID
7993 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7994#endif /* HAVE_SETEUID */
7995#ifdef HAVE_SETEGID
7996 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7997#endif /* HAVE_SETEGID */
7998#ifdef HAVE_SETREUID
7999 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8000#endif /* HAVE_SETREUID */
8001#ifdef HAVE_SETREGID
8002 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8003#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008004#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008005 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008006#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008007#ifdef HAVE_SETGROUPS
8008 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
8009#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008010#ifdef HAVE_GETPGID
8011 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8012#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008013#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008014 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008015#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008016#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008017 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008018#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008019#ifdef HAVE_WAIT3
8020 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8021#endif /* HAVE_WAIT3 */
8022#ifdef HAVE_WAIT4
8023 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8024#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008025#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008026 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008027#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008028#ifdef HAVE_GETSID
8029 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8030#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008031#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008032 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008033#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008034#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008035 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008036#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008037#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008038 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008039#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008040#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008041 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008042#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008043 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8044 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8045 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8046 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8047 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8048 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8049 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8050 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8051 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008052 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008053#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008054 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008055#endif
8056#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008057 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008058#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008059#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008060 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8061#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008062#ifdef HAVE_DEVICE_MACROS
8063 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8064 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8065 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008067#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008068 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008069#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008070#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008071 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008072#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008073#ifdef HAVE_UNSETENV
8074 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8075#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008076#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008077 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008078#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008079#ifdef HAVE_FCHDIR
8080 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8081#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008082#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008083 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008084#endif
8085#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008086 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008087#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008088#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008089#ifdef WCOREDUMP
8090 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8091#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008092#ifdef WIFCONTINUED
8093 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8094#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008095#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008096 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008097#endif /* WIFSTOPPED */
8098#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008099 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008100#endif /* WIFSIGNALED */
8101#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008102 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008103#endif /* WIFEXITED */
8104#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008105 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008106#endif /* WEXITSTATUS */
8107#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008108 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008109#endif /* WTERMSIG */
8110#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008111 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008112#endif /* WSTOPSIG */
8113#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008114#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008115 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008116#endif
8117#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008118 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008119#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008120#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008121 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008122#endif
8123#ifdef HAVE_TEMPNAM
8124 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8125#endif
8126#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008127 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008128#endif
Fred Drakec9680921999-12-13 16:37:25 +00008129#ifdef HAVE_CONFSTR
8130 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8131#endif
8132#ifdef HAVE_SYSCONF
8133 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8134#endif
8135#ifdef HAVE_FPATHCONF
8136 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8137#endif
8138#ifdef HAVE_PATHCONF
8139 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8140#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008141 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008142#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008143 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8144#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008145#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008146 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008147#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008148 #ifdef MS_WINDOWS
8149 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8150 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008151 {NULL, NULL} /* Sentinel */
8152};
8153
8154
Barry Warsaw4a342091996-12-19 23:50:02 +00008155static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008156ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008157{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008158 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008159}
8160
Guido van Rossumd48f2521997-12-05 22:19:34 +00008161#if defined(PYOS_OS2)
8162/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008163static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008164{
8165 APIRET rc;
8166 ULONG values[QSV_MAX+1];
8167 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008168 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008169
8170 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008171 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008172 Py_END_ALLOW_THREADS
8173
8174 if (rc != NO_ERROR) {
8175 os2_error(rc);
8176 return -1;
8177 }
8178
Fred Drake4d1e64b2002-04-15 19:40:07 +00008179 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8180 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8181 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8182 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8183 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8184 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8185 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008186
8187 switch (values[QSV_VERSION_MINOR]) {
8188 case 0: ver = "2.00"; break;
8189 case 10: ver = "2.10"; break;
8190 case 11: ver = "2.11"; break;
8191 case 30: ver = "3.00"; break;
8192 case 40: ver = "4.00"; break;
8193 case 50: ver = "5.00"; break;
8194 default:
Tim Peters885d4572001-11-28 20:27:42 +00008195 PyOS_snprintf(tmp, sizeof(tmp),
8196 "%d-%d", values[QSV_VERSION_MAJOR],
8197 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008198 ver = &tmp[0];
8199 }
8200
8201 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008202 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008203 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008204
8205 /* Add Indicator of Which Drive was Used to Boot the System */
8206 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8207 tmp[1] = ':';
8208 tmp[2] = '\0';
8209
Fred Drake4d1e64b2002-04-15 19:40:07 +00008210 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008211}
8212#endif
8213
Barry Warsaw4a342091996-12-19 23:50:02 +00008214static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008215all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008216{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008217#ifdef F_OK
8218 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008219#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008220#ifdef R_OK
8221 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008222#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008223#ifdef W_OK
8224 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008225#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008226#ifdef X_OK
8227 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008228#endif
Fred Drakec9680921999-12-13 16:37:25 +00008229#ifdef NGROUPS_MAX
8230 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8231#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008232#ifdef TMP_MAX
8233 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8234#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008235#ifdef WCONTINUED
8236 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8237#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008238#ifdef WNOHANG
8239 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008240#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008241#ifdef WUNTRACED
8242 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8243#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008244#ifdef O_RDONLY
8245 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8246#endif
8247#ifdef O_WRONLY
8248 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8249#endif
8250#ifdef O_RDWR
8251 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8252#endif
8253#ifdef O_NDELAY
8254 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8255#endif
8256#ifdef O_NONBLOCK
8257 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8258#endif
8259#ifdef O_APPEND
8260 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8261#endif
8262#ifdef O_DSYNC
8263 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8264#endif
8265#ifdef O_RSYNC
8266 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8267#endif
8268#ifdef O_SYNC
8269 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8270#endif
8271#ifdef O_NOCTTY
8272 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8273#endif
8274#ifdef O_CREAT
8275 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8276#endif
8277#ifdef O_EXCL
8278 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8279#endif
8280#ifdef O_TRUNC
8281 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8282#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008283#ifdef O_BINARY
8284 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8285#endif
8286#ifdef O_TEXT
8287 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8288#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008289#ifdef O_LARGEFILE
8290 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8291#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008292#ifdef O_SHLOCK
8293 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8294#endif
8295#ifdef O_EXLOCK
8296 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8297#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008298
Tim Peters5aa91602002-01-30 05:46:57 +00008299/* MS Windows */
8300#ifdef O_NOINHERIT
8301 /* Don't inherit in child processes. */
8302 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8303#endif
8304#ifdef _O_SHORT_LIVED
8305 /* Optimize for short life (keep in memory). */
8306 /* MS forgot to define this one with a non-underscore form too. */
8307 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8308#endif
8309#ifdef O_TEMPORARY
8310 /* Automatically delete when last handle is closed. */
8311 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8312#endif
8313#ifdef O_RANDOM
8314 /* Optimize for random access. */
8315 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8316#endif
8317#ifdef O_SEQUENTIAL
8318 /* Optimize for sequential access. */
8319 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8320#endif
8321
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008322/* GNU extensions. */
8323#ifdef O_DIRECT
8324 /* Direct disk access. */
8325 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8326#endif
8327#ifdef O_DIRECTORY
8328 /* Must be a directory. */
8329 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8330#endif
8331#ifdef O_NOFOLLOW
8332 /* Do not follow links. */
8333 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8334#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008335
Barry Warsaw5676bd12003-01-07 20:57:09 +00008336 /* These come from sysexits.h */
8337#ifdef EX_OK
8338 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008339#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008340#ifdef EX_USAGE
8341 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008342#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008343#ifdef EX_DATAERR
8344 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008345#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008346#ifdef EX_NOINPUT
8347 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008348#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008349#ifdef EX_NOUSER
8350 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008351#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008352#ifdef EX_NOHOST
8353 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008354#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008355#ifdef EX_UNAVAILABLE
8356 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008357#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008358#ifdef EX_SOFTWARE
8359 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008360#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008361#ifdef EX_OSERR
8362 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008363#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008364#ifdef EX_OSFILE
8365 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008366#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008367#ifdef EX_CANTCREAT
8368 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008369#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008370#ifdef EX_IOERR
8371 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008372#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008373#ifdef EX_TEMPFAIL
8374 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008375#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008376#ifdef EX_PROTOCOL
8377 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008378#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008379#ifdef EX_NOPERM
8380 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008381#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008382#ifdef EX_CONFIG
8383 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008384#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008385#ifdef EX_NOTFOUND
8386 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008387#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008388
Guido van Rossum246bc171999-02-01 23:54:31 +00008389#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008390#if defined(PYOS_OS2) && defined(PYCC_GCC)
8391 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8392 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8393 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8394 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8395 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8396 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8397 if (ins(d, "P_PM", (long)P_PM)) return -1;
8398 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8399 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8400 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8401 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8402 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8403 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8404 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8405 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8406 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8407 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8408 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8409 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8410 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8411#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008412 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8413 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8414 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8415 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8416 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008417#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008418#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008419
Guido van Rossumd48f2521997-12-05 22:19:34 +00008420#if defined(PYOS_OS2)
8421 if (insertvalues(d)) return -1;
8422#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008423 return 0;
8424}
8425
8426
Tim Peters5aa91602002-01-30 05:46:57 +00008427#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008428#define INITFUNC initnt
8429#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008430
8431#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008432#define INITFUNC initos2
8433#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008434
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008435#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008436#define INITFUNC initposix
8437#define MODNAME "posix"
8438#endif
8439
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008440PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008441INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008442{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008443 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008444
Fred Drake4d1e64b2002-04-15 19:40:07 +00008445 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008446 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008447 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008448 if (m == NULL)
8449 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008450
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008451 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008452 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008453 Py_XINCREF(v);
8454 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008455 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008456 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008457
Fred Drake4d1e64b2002-04-15 19:40:07 +00008458 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008459 return;
8460
Fred Drake4d1e64b2002-04-15 19:40:07 +00008461 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008462 return;
8463
Fred Drake4d1e64b2002-04-15 19:40:07 +00008464 Py_INCREF(PyExc_OSError);
8465 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008466
Guido van Rossumb3d39562000-01-31 18:41:26 +00008467#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008468 if (posix_putenv_garbage == NULL)
8469 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008470#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008471
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008472 if (!initialized) {
8473 stat_result_desc.name = MODNAME ".stat_result";
8474 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8475 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8476 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8477 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8478 structseq_new = StatResultType.tp_new;
8479 StatResultType.tp_new = statresult_new;
8480
8481 statvfs_result_desc.name = MODNAME ".statvfs_result";
8482 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8483 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008484 Py_INCREF((PyObject*) &StatResultType);
8485 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008486 Py_INCREF((PyObject*) &StatVFSResultType);
8487 PyModule_AddObject(m, "statvfs_result",
8488 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008489 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008490
8491#ifdef __APPLE__
8492 /*
8493 * Step 2 of weak-linking support on Mac OS X.
8494 *
8495 * The code below removes functions that are not available on the
8496 * currently active platform.
8497 *
8498 * This block allow one to use a python binary that was build on
8499 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8500 * OSX 10.4.
8501 */
8502#ifdef HAVE_FSTATVFS
8503 if (fstatvfs == NULL) {
8504 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8505 return;
8506 }
8507 }
8508#endif /* HAVE_FSTATVFS */
8509
8510#ifdef HAVE_STATVFS
8511 if (statvfs == NULL) {
8512 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8513 return;
8514 }
8515 }
8516#endif /* HAVE_STATVFS */
8517
8518# ifdef HAVE_LCHOWN
8519 if (lchown == NULL) {
8520 if (PyObject_DelAttrString(m, "lchown") == -1) {
8521 return;
8522 }
8523 }
8524#endif /* HAVE_LCHOWN */
8525
8526
8527#endif /* __APPLE__ */
8528
Guido van Rossumb6775db1994-08-01 11:34:53 +00008529}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008530
8531#ifdef __cplusplus
8532}
8533#endif
8534