blob: 4e86d3216fa0cbcc2992d0bb1c59ccb0f2c7b77f [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
Ronald Oussorend06b6f22006-04-23 11:59:25 +000014#ifdef __APPLE__
15 /*
Victor Stinnerd6f85422010-05-05 23:33:33 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Ronald Oussorend06b6f22006-04-23 11:59:25 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
29#include "structseq.h"
Serhiy Storchakada5c2a02013-02-12 09:27:53 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
32#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000033
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000036#endif /* defined(__VMS) */
37
Anthony Baxterac6bd462006-04-13 02:06:09 +000038#ifdef __cplusplus
39extern "C" {
40#endif
41
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000043"This module provides access to operating system functionality that is\n\
44standardized by the C Standard and the POSIX standard (a thinly\n\
45disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000048#ifndef Py_USING_UNICODE
49/* This is used in signatures of functions. */
50#define Py_UNICODE void
51#endif
52
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000053#if defined(PYOS_OS2)
54#define INCL_DOS
55#define INCL_DOSERRORS
56#define INCL_DOSPROCESS
57#define INCL_NOPMAPI
58#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#if defined(PYCC_GCC)
60#include <ctype.h>
61#include <io.h>
62#include <stdio.h>
63#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000064#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000065#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000066#endif
67
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000068#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000070#endif /* HAVE_SYS_TYPES_H */
71
72#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000073#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000074#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000075
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#ifdef HAVE_SYS_WAIT_H
Victor Stinnerd6f85422010-05-05 23:33:33 +000077#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000078#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000079
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000080#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000081#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000082#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000083
Guido van Rossumb6775db1994-08-01 11:34:53 +000084#ifdef HAVE_FCNTL_H
85#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000086#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Guido van Rossuma6535fd2001-10-18 19:44:10 +000088#ifdef HAVE_GRP_H
89#include <grp.h>
90#endif
91
Barry Warsaw5676bd12003-01-07 20:57:09 +000092#ifdef HAVE_SYSEXITS_H
93#include <sysexits.h>
94#endif /* HAVE_SYSEXITS_H */
95
Anthony Baxter8a560de2004-10-13 15:30:56 +000096#ifdef HAVE_SYS_LOADAVG_H
97#include <sys/loadavg.h>
98#endif
99
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000100/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000101/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000103#include <process.h>
104#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000105#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000106#define HAVE_GETCWD 1
107#define HAVE_OPENDIR 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000108#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#if defined(__OS2__)
110#define HAVE_EXECV 1
111#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#include <process.h>
114#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000115#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#define HAVE_EXECV 1
117#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_OPENDIR 1
119#define HAVE_PIPE 1
120#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000121#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000122#define HAVE_WAIT 1
123#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000124#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000125#define HAVE_GETCWD 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000126#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_EXECV 1
128#define HAVE_PIPE 1
129#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000130#define HAVE_SYSTEM 1
131#define HAVE_CWAIT 1
132#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000133#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000134#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000135#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
136/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinnerd6f85422010-05-05 23:33:33 +0000137#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138/* Unix functions that the configure script doesn't check for */
139#define HAVE_EXECV 1
140#define HAVE_FORK 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000141#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000142#define HAVE_FORK1 1
143#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_GETCWD 1
145#define HAVE_GETEGID 1
146#define HAVE_GETEUID 1
147#define HAVE_GETGID 1
148#define HAVE_GETPPID 1
149#define HAVE_GETUID 1
150#define HAVE_KILL 1
151#define HAVE_OPENDIR 1
152#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000153#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000155#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000156#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#define HAVE_WAIT 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000158#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000159#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#endif /* _MSC_VER */
161#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000162#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000164
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000166
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000167#if defined(__sgi)&&_COMPILER_VERSION>=700
168/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
169 (default) */
170extern char *ctermid_r(char *);
171#endif
172
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000173#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000174#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000177#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#endif
183#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chdir(char *);
185extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chdir(const char *);
188extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000189#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000190#ifdef __BORLANDC__
191extern int chmod(const char *, int);
192#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000194#endif
Christian Heimes36281872007-11-30 21:11:28 +0000195/*#ifdef HAVE_FCHMOD
196extern int fchmod(int, mode_t);
197#endif*/
198/*#ifdef HAVE_LCHMOD
199extern int lchmod(const char *, mode_t);
200#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int chown(const char *, uid_t, gid_t);
202extern char *getcwd(char *, int);
203extern char *strerror(int);
204extern int link(const char *, const char *);
205extern int rename(const char *, const char *);
206extern int stat(const char *, struct stat *);
207extern int unlink(const char *);
208extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000211#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000216
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#ifdef HAVE_UTIME_H
220#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000223#ifdef HAVE_SYS_UTIME_H
224#include <sys/utime.h>
225#define HAVE_UTIME_H /* pretend we do for the rest of this file */
226#endif /* HAVE_SYS_UTIME_H */
227
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_SYS_TIMES_H
229#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231
232#ifdef HAVE_SYS_PARAM_H
233#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000234#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
236#ifdef HAVE_SYS_UTSNAME_H
237#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) strlen((dirent)->d_name)
243#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000244#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#include <direct.h>
246#define NAMLEN(dirent) strlen((dirent)->d_name)
247#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000250#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#endif
257#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#endif
260#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000263#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000265#endif
266#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000268#endif
269#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000271#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000272#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000273#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <windows.h>
Victor Stinnerd6f85422010-05-05 23:33:33 +0000275#include <shellapi.h> /* for ShellExecute() */
276#define popen _popen
277#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279
Guido van Rossumd48f2521997-12-05 22:19:34 +0000280#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000282#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
Tim Petersbc2e10e2002-03-03 23:17:02 +0000284#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000285#if defined(PATH_MAX) && PATH_MAX > 1024
286#define MAXPATHLEN PATH_MAX
287#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000289#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#endif /* MAXPATHLEN */
291
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000292#ifdef UNION_WAIT
293/* Emulate some macros on systems that have a union instead of macros */
294
295#ifndef WIFEXITED
296#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
297#endif
298
299#ifndef WEXITSTATUS
300#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
301#endif
302
303#ifndef WTERMSIG
304#define WTERMSIG(u_wait) ((u_wait).w_termsig)
305#endif
306
Neal Norwitzd5a37542006-03-20 06:48:34 +0000307#define WAIT_TYPE union wait
308#define WAIT_STATUS_INT(s) (s.w_status)
309
310#else /* !UNION_WAIT */
311#define WAIT_TYPE int
312#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000313#endif /* UNION_WAIT */
314
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000315/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000316#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000317#define PARSE_PID "i"
318#define PyLong_FromPid PyInt_FromLong
319#define PyLong_AsPid PyInt_AsLong
320#elif SIZEOF_PID_T == SIZEOF_LONG
321#define PARSE_PID "l"
322#define PyLong_FromPid PyInt_FromLong
323#define PyLong_AsPid PyInt_AsLong
324#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
325#define PARSE_PID "L"
326#define PyLong_FromPid PyLong_FromLongLong
327#define PyLong_AsPid PyInt_AsLongLong
328#else
329#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000330#endif /* SIZEOF_PID_T */
331
Greg Wardb48bc172000-03-01 21:51:56 +0000332/* Don't use the "_r" form if we don't need it (also, won't have a
333 prototype for it, at least on Solaris -- maybe others as well?). */
334#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
335#define USE_CTERMID_R
336#endif
337
338#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
339#define USE_TMPNAM_R
340#endif
341
Tim Peters11b23062003-04-23 02:39:17 +0000342#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000343#include <sys/mkdev.h>
344#else
345#if defined(MAJOR_IN_SYSMACROS)
346#include <sys/sysmacros.h>
347#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000348#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
349#include <sys/mkdev.h>
350#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000351#endif
Fred Drake699f3522000-06-29 21:12:41 +0000352
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200353
354#ifndef MS_WINDOWS
355PyObject *
356_PyInt_FromUid(uid_t uid)
357{
358 if (uid <= LONG_MAX)
359 return PyInt_FromLong(uid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500360 return PyLong_FromUnsignedLong(uid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200361}
362
363PyObject *
364_PyInt_FromGid(gid_t gid)
365{
366 if (gid <= LONG_MAX)
367 return PyInt_FromLong(gid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500368 return PyLong_FromUnsignedLong(gid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200369}
370
371int
372_Py_Uid_Converter(PyObject *obj, void *p)
373{
374 int overflow;
375 long result;
376 if (PyFloat_Check(obj)) {
377 PyErr_SetString(PyExc_TypeError,
378 "integer argument expected, got float");
379 return 0;
380 }
381 result = PyLong_AsLongAndOverflow(obj, &overflow);
382 if (overflow < 0)
383 goto OverflowDown;
384 if (!overflow && result == -1) {
385 /* error or -1 */
386 if (PyErr_Occurred())
387 return 0;
388 *(uid_t *)p = (uid_t)-1;
389 }
390 else {
391 /* unsigned uid_t */
392 unsigned long uresult;
393 if (overflow > 0) {
394 uresult = PyLong_AsUnsignedLong(obj);
395 if (PyErr_Occurred()) {
396 if (PyErr_ExceptionMatches(PyExc_OverflowError))
397 goto OverflowUp;
398 return 0;
399 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200400 } else {
401 if (result < 0)
402 goto OverflowDown;
403 uresult = result;
404 }
405 if (sizeof(uid_t) < sizeof(long) &&
406 (unsigned long)(uid_t)uresult != uresult)
407 goto OverflowUp;
408 *(uid_t *)p = (uid_t)uresult;
409 }
410 return 1;
411
412OverflowDown:
413 PyErr_SetString(PyExc_OverflowError,
414 "user id is less than minimum");
415 return 0;
416
417OverflowUp:
418 PyErr_SetString(PyExc_OverflowError,
419 "user id is greater than maximum");
420 return 0;
421}
422
423int
424_Py_Gid_Converter(PyObject *obj, void *p)
425{
426 int overflow;
427 long result;
428 if (PyFloat_Check(obj)) {
429 PyErr_SetString(PyExc_TypeError,
430 "integer argument expected, got float");
431 return 0;
432 }
433 result = PyLong_AsLongAndOverflow(obj, &overflow);
434 if (overflow < 0)
435 goto OverflowDown;
436 if (!overflow && result == -1) {
437 /* error or -1 */
438 if (PyErr_Occurred())
439 return 0;
440 *(gid_t *)p = (gid_t)-1;
441 }
442 else {
443 /* unsigned gid_t */
444 unsigned long uresult;
445 if (overflow > 0) {
446 uresult = PyLong_AsUnsignedLong(obj);
447 if (PyErr_Occurred()) {
448 if (PyErr_ExceptionMatches(PyExc_OverflowError))
449 goto OverflowUp;
450 return 0;
451 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200452 } else {
453 if (result < 0)
454 goto OverflowDown;
455 uresult = result;
456 }
457 if (sizeof(gid_t) < sizeof(long) &&
458 (unsigned long)(gid_t)uresult != uresult)
459 goto OverflowUp;
460 *(gid_t *)p = (gid_t)uresult;
461 }
462 return 1;
463
464OverflowDown:
465 PyErr_SetString(PyExc_OverflowError,
466 "group id is less than minimum");
467 return 0;
468
469OverflowUp:
470 PyErr_SetString(PyExc_OverflowError,
471 "group id is greater than maximum");
472 return 0;
473}
474#endif /* MS_WINDOWS */
475
476
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200477#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
478static int
479_Py_Dev_Converter(PyObject *obj, void *p)
480{
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300481 PyObject *index = PyNumber_Index(obj);
482 if (index == NULL)
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200483 return 0;
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300484 if (PyInt_Check(index)) {
485 long x = PyInt_AS_LONG(index);
486 Py_DECREF(index);
487 if (x == -1 && PyErr_Occurred())
488 return 0;
489 if (x < 0) {
490 PyErr_SetString(PyExc_OverflowError,
491 "can't convert negative number to unsigned long");
492 return 0;
493 }
494 *((dev_t *)p) = (unsigned long)x;
495 }
496 else if (PyLong_Check(index)) {
497#ifdef HAVE_LONG_LONG
498 *((dev_t *)p) = PyLong_AsUnsignedLongLong(index);
499#else
500 *((dev_t *)p) = PyLong_AsUnsignedLong(index);
501#endif
502 Py_DECREF(index);
503 if (PyErr_Occurred())
504 return 0;
505 }
506 else {
507 Py_DECREF(index);
508 PyErr_Format(PyExc_TypeError,
509 "expected int/long, %s found",
510 Py_TYPE(obj)->tp_name);
511 return 0;
512 }
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200513 return 1;
514}
515
516#ifdef HAVE_LONG_LONG
517static PyObject *
518_PyInt_FromDev(PY_LONG_LONG v)
519{
520 if (LONG_MIN <= v && v <= LONG_MAX)
521 return PyInt_FromLong((long)v);
522 else
523 return PyLong_FromLongLong(v);
524}
525#else
526# define _PyInt_FromDev PyInt_FromLong
527#endif
528
529#endif
530
531
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000532#if defined _MSC_VER && _MSC_VER >= 1400
533/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov4bb142b2012-12-18 21:27:37 +0200534 * valid and raise an assertion if it isn't.
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000535 * Normally, an invalid fd is likely to be a C program error and therefore
536 * an assertion can be useful, but it does contradict the POSIX standard
537 * which for write(2) states:
538 * "Otherwise, -1 shall be returned and errno set to indicate the error."
539 * "[EBADF] The fildes argument is not a valid file descriptor open for
540 * writing."
541 * Furthermore, python allows the user to enter any old integer
542 * as a fd and should merely raise a python exception on error.
543 * The Microsoft CRT doesn't provide an official way to check for the
544 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000545 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000546 * internal structures involved.
547 * The structures below must be updated for each version of visual studio
548 * according to the file internal.h in the CRT source, until MS comes
549 * up with a less hacky way to do this.
550 * (all of this is to avoid globally modifying the CRT behaviour using
551 * _set_invalid_parameter_handler() and _CrtSetReportMode())
552 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000553/* The actual size of the structure is determined at runtime.
554 * Only the first items must be present.
555 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000556typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000557 intptr_t osfhnd;
558 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000559} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000560
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000561extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000562#define IOINFO_L2E 5
563#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
564#define IOINFO_ARRAYS 64
565#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
566#define FOPEN 0x01
567#define _NO_CONSOLE_FILENO (intptr_t)-2
568
569/* This function emulates what the windows CRT does to validate file handles */
570int
571_PyVerify_fd(int fd)
572{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000573 const int i1 = fd >> IOINFO_L2E;
574 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000575
Victor Stinnerd6f85422010-05-05 23:33:33 +0000576 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000577
Victor Stinnerd6f85422010-05-05 23:33:33 +0000578 /* Determine the actual size of the ioinfo structure,
579 * as used by the CRT loaded in memory
580 */
581 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
582 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
583 }
584 if (sizeof_ioinfo == 0) {
585 /* This should not happen... */
586 goto fail;
587 }
588
589 /* See that it isn't a special CLEAR fileno */
590 if (fd != _NO_CONSOLE_FILENO) {
591 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
592 * we check pointer validity and other info
593 */
594 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
595 /* finally, check that the file is open */
596 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
597 if (info->osfile & FOPEN) {
598 return 1;
599 }
600 }
601 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000602 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000603 errno = EBADF;
604 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000605}
606
607/* the special case of checking dup2. The target fd must be in a sensible range */
608static int
609_PyVerify_fd_dup2(int fd1, int fd2)
610{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000611 if (!_PyVerify_fd(fd1))
612 return 0;
613 if (fd2 == _NO_CONSOLE_FILENO)
614 return 0;
615 if ((unsigned)fd2 < _NHANDLE_)
616 return 1;
617 else
618 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000619}
620#else
621/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
622#define _PyVerify_fd_dup2(A, B) (1)
623#endif
624
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000625/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100626#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000627/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100628** environ directly, we must obtain it with _NSGetEnviron(). See also
629** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000630*/
631#include <crt_externs.h>
632static char **environ;
633#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000635#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000636
Barry Warsaw53699e91996-12-10 23:23:01 +0000637static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000638convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000640 PyObject *d;
641 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000642#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000643 APIRET rc;
644 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
645#endif
646 d = PyDict_New();
647 if (d == NULL)
648 return NULL;
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100649#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinnerd6f85422010-05-05 23:33:33 +0000650 if (environ == NULL)
651 environ = *_NSGetEnviron();
652#endif
653 if (environ == NULL)
654 return d;
655 /* This part ignores errors */
656 for (e = environ; *e != NULL; e++) {
657 PyObject *k;
658 PyObject *v;
659 char *p = strchr(*e, '=');
660 if (p == NULL)
661 continue;
662 k = PyString_FromStringAndSize(*e, (int)(p-*e));
663 if (k == NULL) {
664 PyErr_Clear();
665 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000666 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000667 v = PyString_FromString(p+1);
668 if (v == NULL) {
669 PyErr_Clear();
670 Py_DECREF(k);
671 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000672 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000673 if (PyDict_GetItem(d, k) == NULL) {
674 if (PyDict_SetItem(d, k, v) != 0)
675 PyErr_Clear();
676 }
677 Py_DECREF(k);
678 Py_DECREF(v);
679 }
680#if defined(PYOS_OS2)
681 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
682 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
683 PyObject *v = PyString_FromString(buffer);
684 PyDict_SetItemString(d, "BEGINLIBPATH", v);
685 Py_DECREF(v);
686 }
687 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
688 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
689 PyObject *v = PyString_FromString(buffer);
690 PyDict_SetItemString(d, "ENDLIBPATH", v);
691 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000692 }
693#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000694 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000695}
696
697
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698/* Set a POSIX-specific error from errno, and return NULL */
699
Barry Warsawd58d7641998-07-23 16:14:40 +0000700static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000701posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000702{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000703 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704}
Barry Warsawd58d7641998-07-23 16:14:40 +0000705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000706posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000707{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000708 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000709}
710
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000711#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000712static PyObject *
713posix_error_with_unicode_filename(Py_UNICODE* name)
714{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000715 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000716}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000717#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000718
719
Mark Hammondef8b6542001-05-13 08:04:26 +0000720static PyObject *
721posix_error_with_allocated_filename(char* name)
722{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000723 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
724 PyMem_Free(name);
725 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000726}
727
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000728#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000729static PyObject *
730win32_error(char* function, char* filename)
731{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000732 /* XXX We should pass the function name along in the future.
733 (_winreg.c also wants to pass the function name.)
734 This would however require an additional param to the
735 Windows error object, which is non-trivial.
736 */
737 errno = GetLastError();
738 if (filename)
739 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
740 else
741 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000742}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000743
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000744static PyObject *
745win32_error_unicode(char* function, Py_UNICODE* filename)
746{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000747 /* XXX - see win32_error for comments on 'function' */
748 errno = GetLastError();
749 if (filename)
750 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
751 else
752 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000753}
754
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000755static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000756convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000757{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000758 if (PyUnicode_CheckExact(*param))
759 Py_INCREF(*param);
760 else if (PyUnicode_Check(*param))
761 /* For a Unicode subtype that's not a Unicode object,
762 return a true Unicode object with the same data. */
763 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
764 PyUnicode_GET_SIZE(*param));
765 else
766 *param = PyUnicode_FromEncodedObject(*param,
767 Py_FileSystemDefaultEncoding,
768 "strict");
769 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000770}
771
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000772#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773
Guido van Rossumd48f2521997-12-05 22:19:34 +0000774#if defined(PYOS_OS2)
775/**********************************************************************
776 * Helper Function to Trim and Format OS/2 Messages
777 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000778static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000779os2_formatmsg(char *msgbuf, int msglen, char *reason)
780{
781 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
782
783 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000784 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000785
Victor Stinner862490a2010-05-06 00:03:44 +0000786 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
787 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000788 }
789
790 /* Add Optional Reason Text */
791 if (reason) {
792 strcat(msgbuf, " : ");
793 strcat(msgbuf, reason);
794 }
795}
796
797/**********************************************************************
798 * Decode an OS/2 Operating System Error Code
799 *
800 * A convenience function to lookup an OS/2 error code and return a
801 * text message we can use to raise a Python exception.
802 *
803 * Notes:
804 * The messages for errors returned from the OS/2 kernel reside in
805 * the file OSO001.MSG in the \OS2 directory hierarchy.
806 *
807 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000808static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000809os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
810{
811 APIRET rc;
812 ULONG msglen;
813
814 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
815 Py_BEGIN_ALLOW_THREADS
816 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
817 errorcode, "oso001.msg", &msglen);
818 Py_END_ALLOW_THREADS
819
820 if (rc == NO_ERROR)
821 os2_formatmsg(msgbuf, msglen, reason);
822 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000823 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000824 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000825
826 return msgbuf;
827}
828
829/* Set an OS/2-specific error and return NULL. OS/2 kernel
830 errors are not in a global variable e.g. 'errno' nor are
831 they congruent with posix error numbers. */
832
Victor Stinnerd6f85422010-05-05 23:33:33 +0000833static PyObject *
834os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000835{
836 char text[1024];
837 PyObject *v;
838
839 os2_strerror(text, sizeof(text), code, "");
840
841 v = Py_BuildValue("(is)", code, text);
842 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000843 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000844 Py_DECREF(v);
845 }
846 return NULL; /* Signal to Python that an Exception is Pending */
847}
848
849#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850
851/* POSIX generic methods */
852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000854posix_fildes(PyObject *fdobj, int (*func)(int))
855{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000856 int fd;
857 int res;
858 fd = PyObject_AsFileDescriptor(fdobj);
859 if (fd < 0)
860 return NULL;
861 if (!_PyVerify_fd(fd))
862 return posix_error();
863 Py_BEGIN_ALLOW_THREADS
864 res = (*func)(fd);
865 Py_END_ALLOW_THREADS
866 if (res < 0)
867 return posix_error();
868 Py_INCREF(Py_None);
869 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000870}
Guido van Rossum21142a01999-01-08 21:05:37 +0000871
872static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000873posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000875 char *path1 = NULL;
876 int res;
877 if (!PyArg_ParseTuple(args, format,
878 Py_FileSystemDefaultEncoding, &path1))
879 return NULL;
880 Py_BEGIN_ALLOW_THREADS
881 res = (*func)(path1);
882 Py_END_ALLOW_THREADS
883 if (res < 0)
884 return posix_error_with_allocated_filename(path1);
885 PyMem_Free(path1);
886 Py_INCREF(Py_None);
887 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888}
889
Barry Warsaw53699e91996-12-10 23:23:01 +0000890static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000891posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000892 char *format,
893 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000894{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000895 char *path1 = NULL, *path2 = NULL;
896 int res;
897 if (!PyArg_ParseTuple(args, format,
898 Py_FileSystemDefaultEncoding, &path1,
899 Py_FileSystemDefaultEncoding, &path2))
900 return NULL;
901 Py_BEGIN_ALLOW_THREADS
902 res = (*func)(path1, path2);
903 Py_END_ALLOW_THREADS
904 PyMem_Free(path1);
905 PyMem_Free(path2);
906 if (res != 0)
907 /* XXX how to report both path1 and path2??? */
908 return posix_error();
909 Py_INCREF(Py_None);
910 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000911}
912
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000913#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000914static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000915win32_1str(PyObject* args, char* func,
916 char* format, BOOL (__stdcall *funcA)(LPCSTR),
917 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000918{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000919 PyObject *uni;
920 char *ansi;
921 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000922
Victor Stinnerd6f85422010-05-05 23:33:33 +0000923 if (!PyArg_ParseTuple(args, wformat, &uni))
924 PyErr_Clear();
925 else {
926 Py_BEGIN_ALLOW_THREADS
927 result = funcW(PyUnicode_AsUnicode(uni));
928 Py_END_ALLOW_THREADS
929 if (!result)
930 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
931 Py_INCREF(Py_None);
932 return Py_None;
933 }
934 if (!PyArg_ParseTuple(args, format, &ansi))
935 return NULL;
936 Py_BEGIN_ALLOW_THREADS
937 result = funcA(ansi);
938 Py_END_ALLOW_THREADS
939 if (!result)
940 return win32_error(func, ansi);
941 Py_INCREF(Py_None);
942 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000943
944}
945
946/* This is a reimplementation of the C library's chdir function,
947 but one that produces Win32 errors instead of DOS error codes.
948 chdir is essentially a wrapper around SetCurrentDirectory; however,
949 it also needs to set "magic" environment variables indicating
950 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000951static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000952win32_chdir(LPCSTR path)
953{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000954 char new_path[MAX_PATH+1];
955 int result;
956 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000957
Victor Stinnerd6f85422010-05-05 23:33:33 +0000958 if(!SetCurrentDirectoryA(path))
959 return FALSE;
960 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
961 if (!result)
962 return FALSE;
963 /* In the ANSI API, there should not be any paths longer
964 than MAX_PATH. */
965 assert(result <= MAX_PATH+1);
966 if (strncmp(new_path, "\\\\", 2) == 0 ||
967 strncmp(new_path, "//", 2) == 0)
968 /* UNC path, nothing to do. */
969 return TRUE;
970 env[1] = new_path[0];
971 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000972}
973
974/* The Unicode version differs from the ANSI version
975 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000976static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000977win32_wchdir(LPCWSTR path)
978{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000979 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
980 int result;
981 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000982
Victor Stinnerd6f85422010-05-05 23:33:33 +0000983 if(!SetCurrentDirectoryW(path))
984 return FALSE;
985 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
986 if (!result)
987 return FALSE;
988 if (result > MAX_PATH+1) {
989 new_path = malloc(result * sizeof(wchar_t));
990 if (!new_path) {
991 SetLastError(ERROR_OUTOFMEMORY);
992 return FALSE;
993 }
994 result = GetCurrentDirectoryW(result, new_path);
995 if (!result) {
996 free(new_path);
997 return FALSE;
998 }
999 }
1000 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1001 wcsncmp(new_path, L"//", 2) == 0)
1002 /* UNC path, nothing to do. */
1003 return TRUE;
1004 env[1] = new_path[0];
1005 result = SetEnvironmentVariableW(env, new_path);
1006 if (new_path != _new_path)
1007 free(new_path);
1008 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001009}
1010#endif
1011
Antoine Pitrouff48c0a2011-07-01 22:56:03 +02001012/* choose the appropriate stat and fstat functions and return structs */
1013#undef STAT
1014#undef FSTAT
1015#undef STRUCT_STAT
1016#if defined(MS_WIN64) || defined(MS_WINDOWS)
1017# define STAT win32_stat
1018# define FSTAT win32_fstat
1019# define STRUCT_STAT struct win32_stat
1020#else
1021# define STAT stat
1022# define FSTAT fstat
1023# define STRUCT_STAT struct stat
1024#endif
1025
Martin v. Löwis14694662006-02-03 12:54:16 +00001026#ifdef MS_WINDOWS
1027/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1028 - time stamps are restricted to second resolution
1029 - file modification times suffer from forth-and-back conversions between
1030 UTC and local time
1031 Therefore, we implement our own stat, based on the Win32 API directly.
1032*/
Victor Stinnerd6f85422010-05-05 23:33:33 +00001033#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001034
1035struct win32_stat{
1036 int st_dev;
1037 __int64 st_ino;
1038 unsigned short st_mode;
1039 int st_nlink;
1040 int st_uid;
1041 int st_gid;
1042 int st_rdev;
1043 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001044 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001045 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001046 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001047 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001048 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001049 int st_ctime_nsec;
1050};
1051
1052static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1053
1054static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001055FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001056{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001057 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1058 /* Cannot simply cast and dereference in_ptr,
1059 since it might not be aligned properly */
1060 __int64 in;
1061 memcpy(&in, in_ptr, sizeof(in));
1062 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001063 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001064}
1065
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001066static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001067time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001068{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001069 /* XXX endianness */
1070 __int64 out;
1071 out = time_in + secs_between_epochs;
1072 out = out * 10000000 + nsec_in / 100;
1073 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001074}
1075
Martin v. Löwis14694662006-02-03 12:54:16 +00001076/* Below, we *know* that ugo+r is 0444 */
1077#if _S_IREAD != 0400
1078#error Unsupported C library
1079#endif
1080static int
1081attributes_to_mode(DWORD attr)
1082{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001083 int m = 0;
1084 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1085 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1086 else
1087 m |= _S_IFREG;
1088 if (attr & FILE_ATTRIBUTE_READONLY)
1089 m |= 0444;
1090 else
1091 m |= 0666;
1092 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001093}
1094
1095static int
1096attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
1097{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001098 memset(result, 0, sizeof(*result));
1099 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1100 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1101 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1102 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1103 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001104
Victor Stinnerd6f85422010-05-05 23:33:33 +00001105 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001106}
1107
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001108static BOOL
1109attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001111 HANDLE hFindFile;
1112 WIN32_FIND_DATAA FileData;
1113 hFindFile = FindFirstFileA(pszFile, &FileData);
1114 if (hFindFile == INVALID_HANDLE_VALUE)
1115 return FALSE;
1116 FindClose(hFindFile);
1117 pfad->dwFileAttributes = FileData.dwFileAttributes;
1118 pfad->ftCreationTime = FileData.ftCreationTime;
1119 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1120 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1121 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1122 pfad->nFileSizeLow = FileData.nFileSizeLow;
1123 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001124}
1125
1126static BOOL
1127attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1128{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001129 HANDLE hFindFile;
1130 WIN32_FIND_DATAW FileData;
1131 hFindFile = FindFirstFileW(pszFile, &FileData);
1132 if (hFindFile == INVALID_HANDLE_VALUE)
1133 return FALSE;
1134 FindClose(hFindFile);
1135 pfad->dwFileAttributes = FileData.dwFileAttributes;
1136 pfad->ftCreationTime = FileData.ftCreationTime;
1137 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1138 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1139 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1140 pfad->nFileSizeLow = FileData.nFileSizeLow;
1141 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001142}
1143
Victor Stinnerd6f85422010-05-05 23:33:33 +00001144static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001145win32_stat(const char* path, struct win32_stat *result)
1146{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001147 WIN32_FILE_ATTRIBUTE_DATA info;
1148 int code;
1149 char *dot;
1150 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1151 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1152 /* Protocol violation: we explicitly clear errno, instead of
1153 setting it to a POSIX error. Callers should use GetLastError. */
1154 errno = 0;
1155 return -1;
1156 } else {
1157 /* Could not get attributes on open file. Fall back to
1158 reading the directory. */
1159 if (!attributes_from_dir(path, &info)) {
1160 /* Very strange. This should not fail now */
1161 errno = 0;
1162 return -1;
1163 }
1164 }
1165 }
1166 code = attribute_data_to_stat(&info, result);
1167 if (code != 0)
1168 return code;
1169 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1170 dot = strrchr(path, '.');
1171 if (dot) {
1172 if (stricmp(dot, ".bat") == 0 ||
1173 stricmp(dot, ".cmd") == 0 ||
1174 stricmp(dot, ".exe") == 0 ||
1175 stricmp(dot, ".com") == 0)
1176 result->st_mode |= 0111;
1177 }
1178 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001179}
1180
Victor Stinnerd6f85422010-05-05 23:33:33 +00001181static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001182win32_wstat(const wchar_t* path, struct win32_stat *result)
1183{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001184 int code;
1185 const wchar_t *dot;
1186 WIN32_FILE_ATTRIBUTE_DATA info;
1187 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1188 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1189 /* Protocol violation: we explicitly clear errno, instead of
1190 setting it to a POSIX error. Callers should use GetLastError. */
1191 errno = 0;
1192 return -1;
1193 } else {
1194 /* Could not get attributes on open file. Fall back to
1195 reading the directory. */
1196 if (!attributes_from_dir_w(path, &info)) {
1197 /* Very strange. This should not fail now */
1198 errno = 0;
1199 return -1;
1200 }
1201 }
1202 }
1203 code = attribute_data_to_stat(&info, result);
1204 if (code < 0)
1205 return code;
1206 /* Set IFEXEC if it is an .exe, .bat, ... */
1207 dot = wcsrchr(path, '.');
1208 if (dot) {
1209 if (_wcsicmp(dot, L".bat") == 0 ||
1210 _wcsicmp(dot, L".cmd") == 0 ||
1211 _wcsicmp(dot, L".exe") == 0 ||
1212 _wcsicmp(dot, L".com") == 0)
1213 result->st_mode |= 0111;
1214 }
1215 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001216}
1217
1218static int
1219win32_fstat(int file_number, struct win32_stat *result)
1220{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001221 BY_HANDLE_FILE_INFORMATION info;
1222 HANDLE h;
1223 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001224
Victor Stinnerd6f85422010-05-05 23:33:33 +00001225 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001226
Victor Stinnerd6f85422010-05-05 23:33:33 +00001227 /* Protocol violation: we explicitly clear errno, instead of
1228 setting it to a POSIX error. Callers should use GetLastError. */
1229 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001230
Victor Stinnerd6f85422010-05-05 23:33:33 +00001231 if (h == INVALID_HANDLE_VALUE) {
1232 /* This is really a C library error (invalid file handle).
1233 We set the Win32 error to the closes one matching. */
1234 SetLastError(ERROR_INVALID_HANDLE);
1235 return -1;
1236 }
1237 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001238
Victor Stinnerd6f85422010-05-05 23:33:33 +00001239 type = GetFileType(h);
1240 if (type == FILE_TYPE_UNKNOWN) {
1241 DWORD error = GetLastError();
1242 if (error != 0) {
1243 return -1;
1244 }
1245 /* else: valid but unknown file */
1246 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001247
Victor Stinnerd6f85422010-05-05 23:33:33 +00001248 if (type != FILE_TYPE_DISK) {
1249 if (type == FILE_TYPE_CHAR)
1250 result->st_mode = _S_IFCHR;
1251 else if (type == FILE_TYPE_PIPE)
1252 result->st_mode = _S_IFIFO;
1253 return 0;
1254 }
1255
1256 if (!GetFileInformationByHandle(h, &info)) {
1257 return -1;
1258 }
1259
1260 /* similar to stat() */
1261 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1262 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1263 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1264 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1265 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1266 /* specific to fstat() */
1267 result->st_nlink = info.nNumberOfLinks;
1268 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1269 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001270}
1271
1272#endif /* MS_WINDOWS */
1273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001274PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001275"stat_result: Result from stat or lstat.\n\n\
1276This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001277 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1279\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001280Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1281or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001282\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001283See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284
1285static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001286 {"st_mode", "protection bits"},
1287 {"st_ino", "inode"},
1288 {"st_dev", "device"},
1289 {"st_nlink", "number of hard links"},
1290 {"st_uid", "user ID of owner"},
1291 {"st_gid", "group ID of owner"},
1292 {"st_size", "total size, in bytes"},
1293 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1294 {NULL, "integer time of last access"},
1295 {NULL, "integer time of last modification"},
1296 {NULL, "integer time of last change"},
1297 {"st_atime", "time of last access"},
1298 {"st_mtime", "time of last modification"},
1299 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001300#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001301 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001302#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001303#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001304 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001305#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001306#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001308#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001309#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001310 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001311#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001312#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001313 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001314#endif
1315#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001316 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001317#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001318 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319};
1320
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001321#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001322#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001324#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001325#endif
1326
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001327#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001328#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1329#else
1330#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1331#endif
1332
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001333#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1335#else
1336#define ST_RDEV_IDX ST_BLOCKS_IDX
1337#endif
1338
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001339#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1340#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1341#else
1342#define ST_FLAGS_IDX ST_RDEV_IDX
1343#endif
1344
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001345#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001346#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001347#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001348#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001349#endif
1350
1351#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1352#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1353#else
1354#define ST_BIRTHTIME_IDX ST_GEN_IDX
1355#endif
1356
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001357static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001358 "stat_result", /* name */
1359 stat_result__doc__, /* doc */
1360 stat_result_fields,
1361 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001362};
1363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001365"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1366This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001367 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001368or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001371
1372static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001373 {"f_bsize", },
1374 {"f_frsize", },
1375 {"f_blocks", },
1376 {"f_bfree", },
1377 {"f_bavail", },
1378 {"f_files", },
1379 {"f_ffree", },
1380 {"f_favail", },
1381 {"f_flag", },
1382 {"f_namemax",},
1383 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384};
1385
1386static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001387 "statvfs_result", /* name */
1388 statvfs_result__doc__, /* doc */
1389 statvfs_result_fields,
1390 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001391};
1392
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001393static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001394static PyTypeObject StatResultType;
1395static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001396static newfunc structseq_new;
1397
1398static PyObject *
1399statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1400{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001401 PyStructSequence *result;
1402 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001403
Victor Stinnerd6f85422010-05-05 23:33:33 +00001404 result = (PyStructSequence*)structseq_new(type, args, kwds);
1405 if (!result)
1406 return NULL;
1407 /* If we have been initialized from a tuple,
1408 st_?time might be set to None. Initialize it
1409 from the int slots. */
1410 for (i = 7; i <= 9; i++) {
1411 if (result->ob_item[i+3] == Py_None) {
1412 Py_DECREF(Py_None);
1413 Py_INCREF(result->ob_item[i]);
1414 result->ob_item[i+3] = result->ob_item[i];
1415 }
1416 }
1417 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001418}
1419
1420
1421
1422/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001423static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001424
1425PyDoc_STRVAR(stat_float_times__doc__,
1426"stat_float_times([newval]) -> oldval\n\n\
1427Determine whether os.[lf]stat represents time stamps as float objects.\n\
1428If newval is True, future calls to stat() return floats, if it is False,\n\
1429future calls return ints. \n\
1430If newval is omitted, return the current setting.\n");
1431
1432static PyObject*
1433stat_float_times(PyObject* self, PyObject *args)
1434{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001435 int newval = -1;
1436 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1437 return NULL;
1438 if (newval == -1)
1439 /* Return old value */
1440 return PyBool_FromLong(_stat_float_times);
1441 _stat_float_times = newval;
1442 Py_INCREF(Py_None);
1443 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001444}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001445
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001446static void
1447fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1448{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001449 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001450#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001451 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001452#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001453 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001454#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001455 if (!ival)
1456 return;
1457 if (_stat_float_times) {
1458 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1459 } else {
1460 fval = ival;
1461 Py_INCREF(fval);
1462 }
1463 PyStructSequence_SET_ITEM(v, index, ival);
1464 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001465}
1466
Tim Peters5aa91602002-01-30 05:46:57 +00001467/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001468 (used by posix_stat() and posix_fstat()) */
1469static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001470_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001471{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001472 unsigned long ansec, mnsec, cnsec;
1473 PyObject *v = PyStructSequence_New(&StatResultType);
1474 if (v == NULL)
1475 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001476
Victor Stinnerd6f85422010-05-05 23:33:33 +00001477 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001478#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001479 PyStructSequence_SET_ITEM(v, 1,
1480 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001481#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001482 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001483#endif
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001484#ifdef MS_WINDOWS
1485 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001486#else
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001487 PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001488#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001489 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02001490#if defined(MS_WINDOWS)
1491 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
1492 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
1493#else
1494 PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
1495 PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
1496#endif
Fred Drake699f3522000-06-29 21:12:41 +00001497#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001498 PyStructSequence_SET_ITEM(v, 6,
1499 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001500#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001501 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001502#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001503
Martin v. Löwis14694662006-02-03 12:54:16 +00001504#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001505 ansec = st->st_atim.tv_nsec;
1506 mnsec = st->st_mtim.tv_nsec;
1507 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001508#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001509 ansec = st->st_atimespec.tv_nsec;
1510 mnsec = st->st_mtimespec.tv_nsec;
1511 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001512#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001513 ansec = st->st_atime_nsec;
1514 mnsec = st->st_mtime_nsec;
1515 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001516#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001517 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001518#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001519 fill_time(v, 7, st->st_atime, ansec);
1520 fill_time(v, 8, st->st_mtime, mnsec);
1521 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001522
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001523#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001524 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1525 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001526#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001527#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001528 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1529 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001530#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001531#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001532 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1533 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001534#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001535#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001536 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1537 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001538#endif
1539#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001540 {
1541 PyObject *val;
1542 unsigned long bsec,bnsec;
1543 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001544#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001545 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001546#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001547 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001548#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001549 if (_stat_float_times) {
1550 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1551 } else {
1552 val = PyInt_FromLong((long)bsec);
1553 }
1554 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1555 val);
1556 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001557#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001558#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001559 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1560 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001561#endif
Fred Drake699f3522000-06-29 21:12:41 +00001562
Victor Stinnerd6f85422010-05-05 23:33:33 +00001563 if (PyErr_Occurred()) {
1564 Py_DECREF(v);
1565 return NULL;
1566 }
Fred Drake699f3522000-06-29 21:12:41 +00001567
Victor Stinnerd6f85422010-05-05 23:33:33 +00001568 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001569}
1570
Martin v. Löwisd8948722004-06-02 09:57:56 +00001571#ifdef MS_WINDOWS
1572
1573/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1574 where / can be used in place of \ and the trailing slash is optional.
1575 Both SERVER and SHARE must have at least one character.
1576*/
1577
1578#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1579#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001580#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001581#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001582#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001583
Tim Peters4ad82172004-08-30 17:02:04 +00001584static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001585IsUNCRootA(char *path, int pathlen)
1586{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001587 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001588
Victor Stinnerd6f85422010-05-05 23:33:33 +00001589 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001590
Victor Stinnerd6f85422010-05-05 23:33:33 +00001591 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1592 /* minimum UNCRoot is \\x\y */
1593 return FALSE;
1594 for (i = 2; i < pathlen ; i++)
1595 if (ISSLASH(path[i])) break;
1596 if (i == 2 || i == pathlen)
1597 /* do not allow \\\SHARE or \\SERVER */
1598 return FALSE;
1599 share = i+1;
1600 for (i = share; i < pathlen; i++)
1601 if (ISSLASH(path[i])) break;
1602 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001603
Victor Stinnerd6f85422010-05-05 23:33:33 +00001604 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001605}
1606
Tim Peters4ad82172004-08-30 17:02:04 +00001607static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001608IsUNCRootW(Py_UNICODE *path, int pathlen)
1609{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001610 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001611
Victor Stinnerd6f85422010-05-05 23:33:33 +00001612 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001613
Victor Stinnerd6f85422010-05-05 23:33:33 +00001614 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1615 /* minimum UNCRoot is \\x\y */
1616 return FALSE;
1617 for (i = 2; i < pathlen ; i++)
1618 if (ISSLASH(path[i])) break;
1619 if (i == 2 || i == pathlen)
1620 /* do not allow \\\SHARE or \\SERVER */
1621 return FALSE;
1622 share = i+1;
1623 for (i = share; i < pathlen; i++)
1624 if (ISSLASH(path[i])) break;
1625 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001626
Victor Stinnerd6f85422010-05-05 23:33:33 +00001627 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001628}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001629#endif /* MS_WINDOWS */
1630
Barry Warsaw53699e91996-12-10 23:23:01 +00001631static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001632posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001633 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001634#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001635 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001636#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001637 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001638#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001639 char *wformat,
1640 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 STRUCT_STAT st;
1643 char *path = NULL; /* pass this to stat; do not free() it */
1644 char *pathfree = NULL; /* this memory must be free'd */
1645 int res;
1646 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001648#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001649 PyUnicodeObject *po;
1650 if (PyArg_ParseTuple(args, wformat, &po)) {
1651 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001652
Victor Stinnerd6f85422010-05-05 23:33:33 +00001653 Py_BEGIN_ALLOW_THREADS
1654 /* PyUnicode_AS_UNICODE result OK without
1655 thread lock as it is a simple dereference. */
1656 res = wstatfunc(wpath, &st);
1657 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001658
Victor Stinnerd6f85422010-05-05 23:33:33 +00001659 if (res != 0)
1660 return win32_error_unicode("stat", wpath);
1661 return _pystat_fromstructstat(&st);
1662 }
1663 /* Drop the argument parsing error as narrow strings
1664 are also valid. */
1665 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001666#endif
1667
Victor Stinnerd6f85422010-05-05 23:33:33 +00001668 if (!PyArg_ParseTuple(args, format,
1669 Py_FileSystemDefaultEncoding, &path))
1670 return NULL;
1671 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001672
Victor Stinnerd6f85422010-05-05 23:33:33 +00001673 Py_BEGIN_ALLOW_THREADS
1674 res = (*statfunc)(path, &st);
1675 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001676
Victor Stinnerd6f85422010-05-05 23:33:33 +00001677 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001678#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001679 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001680#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001681 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001682#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001683 }
1684 else
1685 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001686
Victor Stinnerd6f85422010-05-05 23:33:33 +00001687 PyMem_Free(pathfree);
1688 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001689}
1690
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691/* POSIX methods */
1692
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001694"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001695Use the real uid/gid to test for access to a path. Note that most\n\
1696operations will use the effective uid/gid, therefore this routine can\n\
1697be used in a suid/sgid environment to test if the invoking user has the\n\
1698specified access to the path. The mode argument can be F_OK to test\n\
1699existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001700
1701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001702posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001703{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001704 char *path;
1705 int mode;
1706
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001707#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001708 DWORD attr;
1709 PyUnicodeObject *po;
1710 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1711 Py_BEGIN_ALLOW_THREADS
1712 /* PyUnicode_AS_UNICODE OK without thread lock as
1713 it is a simple dereference. */
1714 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1715 Py_END_ALLOW_THREADS
1716 goto finish;
1717 }
1718 /* Drop the argument parsing error as narrow strings
1719 are also valid. */
1720 PyErr_Clear();
1721 if (!PyArg_ParseTuple(args, "eti:access",
1722 Py_FileSystemDefaultEncoding, &path, &mode))
1723 return NULL;
1724 Py_BEGIN_ALLOW_THREADS
1725 attr = GetFileAttributesA(path);
1726 Py_END_ALLOW_THREADS
1727 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001728finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001729 if (attr == 0xFFFFFFFF)
1730 /* File does not exist, or cannot read attributes */
1731 return PyBool_FromLong(0);
1732 /* Access is possible if either write access wasn't requested, or
1733 the file isn't read-only, or if it's a directory, as there are
1734 no read-only directories on Windows. */
1735 return PyBool_FromLong(!(mode & 2)
1736 || !(attr & FILE_ATTRIBUTE_READONLY)
1737 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001738#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001739 int res;
1740 if (!PyArg_ParseTuple(args, "eti:access",
1741 Py_FileSystemDefaultEncoding, &path, &mode))
1742 return NULL;
1743 Py_BEGIN_ALLOW_THREADS
1744 res = access(path, mode);
1745 Py_END_ALLOW_THREADS
1746 PyMem_Free(path);
1747 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001748#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749}
1750
Guido van Rossumd371ff11999-01-25 16:12:23 +00001751#ifndef F_OK
1752#define F_OK 0
1753#endif
1754#ifndef R_OK
1755#define R_OK 4
1756#endif
1757#ifndef W_OK
1758#define W_OK 2
1759#endif
1760#ifndef X_OK
1761#define X_OK 1
1762#endif
1763
1764#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001768
1769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001770posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001772 int id;
1773 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774
Victor Stinnerd6f85422010-05-05 23:33:33 +00001775 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1776 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001777
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001778#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001779 /* file descriptor 0 only, the default input device (stdin) */
1780 if (id == 0) {
1781 ret = ttyname();
1782 }
1783 else {
1784 ret = NULL;
1785 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001786#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001787 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001789 if (ret == NULL)
1790 return posix_error();
1791 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001792}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001793#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001795#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001796PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001797"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799
1800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001801posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001803 char *ret;
1804 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001805
Greg Wardb48bc172000-03-01 21:51:56 +00001806#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001807 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001809 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001811 if (ret == NULL)
1812 return posix_error();
1813 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001814}
1815#endif
1816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001820
Barry Warsaw53699e91996-12-10 23:23:01 +00001821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001823{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001824#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001825 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001827 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001828#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001829 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001830#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001831 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833}
1834
Fred Drake4d1e64b2002-04-15 19:40:07 +00001835#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840
1841static PyObject *
1842posix_fchdir(PyObject *self, PyObject *fdobj)
1843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001844 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001845}
1846#endif /* HAVE_FCHDIR */
1847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001850"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001852
Barry Warsaw53699e91996-12-10 23:23:01 +00001853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001854posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001856 char *path = NULL;
1857 int i;
1858 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001859#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001860 DWORD attr;
1861 PyUnicodeObject *po;
1862 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1863 Py_BEGIN_ALLOW_THREADS
1864 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1865 if (attr != 0xFFFFFFFF) {
1866 if (i & _S_IWRITE)
1867 attr &= ~FILE_ATTRIBUTE_READONLY;
1868 else
1869 attr |= FILE_ATTRIBUTE_READONLY;
1870 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1871 }
1872 else
1873 res = 0;
1874 Py_END_ALLOW_THREADS
1875 if (!res)
1876 return win32_error_unicode("chmod",
1877 PyUnicode_AS_UNICODE(po));
1878 Py_INCREF(Py_None);
1879 return Py_None;
1880 }
1881 /* Drop the argument parsing error as narrow strings
1882 are also valid. */
1883 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001884
Victor Stinnerd6f85422010-05-05 23:33:33 +00001885 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1886 &path, &i))
1887 return NULL;
1888 Py_BEGIN_ALLOW_THREADS
1889 attr = GetFileAttributesA(path);
1890 if (attr != 0xFFFFFFFF) {
1891 if (i & _S_IWRITE)
1892 attr &= ~FILE_ATTRIBUTE_READONLY;
1893 else
1894 attr |= FILE_ATTRIBUTE_READONLY;
1895 res = SetFileAttributesA(path, attr);
1896 }
1897 else
1898 res = 0;
1899 Py_END_ALLOW_THREADS
1900 if (!res) {
1901 win32_error("chmod", path);
1902 PyMem_Free(path);
1903 return NULL;
1904 }
1905 PyMem_Free(path);
1906 Py_INCREF(Py_None);
1907 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001908#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001909 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1910 &path, &i))
1911 return NULL;
1912 Py_BEGIN_ALLOW_THREADS
1913 res = chmod(path, i);
1914 Py_END_ALLOW_THREADS
1915 if (res < 0)
1916 return posix_error_with_allocated_filename(path);
1917 PyMem_Free(path);
1918 Py_INCREF(Py_None);
1919 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001920#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001921}
1922
Christian Heimes36281872007-11-30 21:11:28 +00001923#ifdef HAVE_FCHMOD
1924PyDoc_STRVAR(posix_fchmod__doc__,
1925"fchmod(fd, mode)\n\n\
1926Change the access permissions of the file given by file\n\
1927descriptor fd.");
1928
1929static PyObject *
1930posix_fchmod(PyObject *self, PyObject *args)
1931{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001932 int fd, mode, res;
1933 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1934 return NULL;
1935 Py_BEGIN_ALLOW_THREADS
1936 res = fchmod(fd, mode);
1937 Py_END_ALLOW_THREADS
1938 if (res < 0)
1939 return posix_error();
1940 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001941}
1942#endif /* HAVE_FCHMOD */
1943
1944#ifdef HAVE_LCHMOD
1945PyDoc_STRVAR(posix_lchmod__doc__,
1946"lchmod(path, mode)\n\n\
1947Change the access permissions of a file. If path is a symlink, this\n\
1948affects the link itself rather than the target.");
1949
1950static PyObject *
1951posix_lchmod(PyObject *self, PyObject *args)
1952{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001953 char *path = NULL;
1954 int i;
1955 int res;
1956 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1957 &path, &i))
1958 return NULL;
1959 Py_BEGIN_ALLOW_THREADS
1960 res = lchmod(path, i);
1961 Py_END_ALLOW_THREADS
1962 if (res < 0)
1963 return posix_error_with_allocated_filename(path);
1964 PyMem_Free(path);
1965 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001966}
1967#endif /* HAVE_LCHMOD */
1968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Martin v. Löwis382abef2007-02-19 10:55:19 +00001970#ifdef HAVE_CHFLAGS
1971PyDoc_STRVAR(posix_chflags__doc__,
1972"chflags(path, flags)\n\n\
1973Set file flags.");
1974
1975static PyObject *
1976posix_chflags(PyObject *self, PyObject *args)
1977{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001978 char *path;
1979 unsigned long flags;
1980 int res;
1981 if (!PyArg_ParseTuple(args, "etk:chflags",
1982 Py_FileSystemDefaultEncoding, &path, &flags))
1983 return NULL;
1984 Py_BEGIN_ALLOW_THREADS
1985 res = chflags(path, flags);
1986 Py_END_ALLOW_THREADS
1987 if (res < 0)
1988 return posix_error_with_allocated_filename(path);
1989 PyMem_Free(path);
1990 Py_INCREF(Py_None);
1991 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001992}
1993#endif /* HAVE_CHFLAGS */
1994
1995#ifdef HAVE_LCHFLAGS
1996PyDoc_STRVAR(posix_lchflags__doc__,
1997"lchflags(path, flags)\n\n\
1998Set file flags.\n\
1999This function will not follow symbolic links.");
2000
2001static PyObject *
2002posix_lchflags(PyObject *self, PyObject *args)
2003{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002004 char *path;
2005 unsigned long flags;
2006 int res;
2007 if (!PyArg_ParseTuple(args, "etk:lchflags",
2008 Py_FileSystemDefaultEncoding, &path, &flags))
2009 return NULL;
2010 Py_BEGIN_ALLOW_THREADS
2011 res = lchflags(path, flags);
2012 Py_END_ALLOW_THREADS
2013 if (res < 0)
2014 return posix_error_with_allocated_filename(path);
2015 PyMem_Free(path);
2016 Py_INCREF(Py_None);
2017 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00002018}
2019#endif /* HAVE_LCHFLAGS */
2020
Martin v. Löwis244edc82001-10-04 22:44:26 +00002021#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002023"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002025
2026static PyObject *
2027posix_chroot(PyObject *self, PyObject *args)
2028{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002029 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002030}
2031#endif
2032
Guido van Rossum21142a01999-01-08 21:05:37 +00002033#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002035"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002036force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002037
2038static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002039posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002040{
Stefan Krah93f7a322010-11-26 17:35:50 +00002041 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002042}
2043#endif /* HAVE_FSYNC */
2044
2045#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002046
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002047#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002048extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2049#endif
2050
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002052"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002053force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002055
2056static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002057posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002058{
Stefan Krah93f7a322010-11-26 17:35:50 +00002059 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002060}
2061#endif /* HAVE_FDATASYNC */
2062
2063
Fredrik Lundh10723342000-07-10 16:38:09 +00002064#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002066"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002067Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Barry Warsaw53699e91996-12-10 23:23:01 +00002069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002070posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002072 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002073 uid_t uid;
2074 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002075 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002076 if (!PyArg_ParseTuple(args, "etO&O&:chown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002077 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002078 _Py_Uid_Converter, &uid,
2079 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002080 return NULL;
2081 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002082 res = chown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002083 Py_END_ALLOW_THREADS
2084 if (res < 0)
2085 return posix_error_with_allocated_filename(path);
2086 PyMem_Free(path);
2087 Py_INCREF(Py_None);
2088 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002089}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002090#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002091
Christian Heimes36281872007-11-30 21:11:28 +00002092#ifdef HAVE_FCHOWN
2093PyDoc_STRVAR(posix_fchown__doc__,
2094"fchown(fd, uid, gid)\n\n\
2095Change the owner and group id of the file given by file descriptor\n\
2096fd to the numeric uid and gid.");
2097
2098static PyObject *
2099posix_fchown(PyObject *self, PyObject *args)
2100{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002101 int fd;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002102 uid_t uid;
2103 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002104 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002105 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
2106 _Py_Uid_Converter, &uid,
2107 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002108 return NULL;
2109 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002110 res = fchown(fd, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002111 Py_END_ALLOW_THREADS
2112 if (res < 0)
2113 return posix_error();
2114 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00002115}
2116#endif /* HAVE_FCHOWN */
2117
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002118#ifdef HAVE_LCHOWN
2119PyDoc_STRVAR(posix_lchown__doc__,
2120"lchown(path, uid, gid)\n\n\
2121Change the owner and group id of path to the numeric uid and gid.\n\
2122This function will not follow symbolic links.");
2123
2124static PyObject *
2125posix_lchown(PyObject *self, PyObject *args)
2126{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002127 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002128 uid_t uid;
2129 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002130 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002131 if (!PyArg_ParseTuple(args, "etO&O&:lchown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002132 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002133 _Py_Uid_Converter, &uid,
2134 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002135 return NULL;
2136 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002137 res = lchown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002138 Py_END_ALLOW_THREADS
2139 if (res < 0)
2140 return posix_error_with_allocated_filename(path);
2141 PyMem_Free(path);
2142 Py_INCREF(Py_None);
2143 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002144}
2145#endif /* HAVE_LCHOWN */
2146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002147
Guido van Rossum36bc6801995-06-14 22:54:23 +00002148#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002149PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002150"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002151Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002152
Trent Nelsonda4277a2012-08-29 09:20:41 -04002153#if (defined(__sun) && defined(__SVR4)) || \
2154 defined(__OpenBSD__) || \
2155 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00002156/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
2157static PyObject *
2158posix_getcwd(PyObject *self, PyObject *noargs)
2159{
2160 char buf[PATH_MAX+2];
2161 char *res;
2162
2163 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00002164 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00002165 Py_END_ALLOW_THREADS
2166
2167 if (res == NULL)
2168 return posix_error();
2169
2170 return PyString_FromString(buf);
2171}
2172#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002173static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002174posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002175{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002176 int bufsize_incr = 1024;
2177 int bufsize = 0;
2178 char *tmpbuf = NULL;
2179 char *res = NULL;
2180 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002181
Victor Stinnerd6f85422010-05-05 23:33:33 +00002182 Py_BEGIN_ALLOW_THREADS
2183 do {
2184 bufsize = bufsize + bufsize_incr;
2185 tmpbuf = malloc(bufsize);
2186 if (tmpbuf == NULL) {
2187 break;
2188 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002189#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002190 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002191#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002192 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002193#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002194
Victor Stinnerd6f85422010-05-05 23:33:33 +00002195 if (res == NULL) {
2196 free(tmpbuf);
2197 }
2198 } while ((res == NULL) && (errno == ERANGE));
2199 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002200
Victor Stinnerd6f85422010-05-05 23:33:33 +00002201 if (res == NULL)
2202 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002203
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 dynamic_return = PyString_FromString(tmpbuf);
2205 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002206
Victor Stinnerd6f85422010-05-05 23:33:33 +00002207 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002208}
Stefan Krah182ae642010-07-13 19:17:08 +00002209#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002210
Walter Dörwald3b918c32002-11-21 20:18:46 +00002211#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002212PyDoc_STRVAR(posix_getcwdu__doc__,
2213"getcwdu() -> path\n\n\
2214Return a unicode string representing the current working directory.");
2215
2216static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002217posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002218{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002219 char buf[1026];
2220 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002221
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002222#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002223 DWORD len;
2224 wchar_t wbuf[1026];
2225 wchar_t *wbuf2 = wbuf;
2226 PyObject *resobj;
2227 Py_BEGIN_ALLOW_THREADS
2228 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2229 /* If the buffer is large enough, len does not include the
2230 terminating \0. If the buffer is too small, len includes
2231 the space needed for the terminator. */
2232 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2233 wbuf2 = malloc(len * sizeof(wchar_t));
2234 if (wbuf2)
2235 len = GetCurrentDirectoryW(len, wbuf2);
2236 }
2237 Py_END_ALLOW_THREADS
2238 if (!wbuf2) {
2239 PyErr_NoMemory();
2240 return NULL;
2241 }
2242 if (!len) {
2243 if (wbuf2 != wbuf) free(wbuf2);
2244 return win32_error("getcwdu", NULL);
2245 }
2246 resobj = PyUnicode_FromWideChar(wbuf2, len);
2247 if (wbuf2 != wbuf) free(wbuf2);
2248 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002249#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002250
Victor Stinnerd6f85422010-05-05 23:33:33 +00002251 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002253 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002254#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002255 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002256#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002257 Py_END_ALLOW_THREADS
2258 if (res == NULL)
2259 return posix_error();
2260 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002261}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002262#endif /* Py_USING_UNICODE */
2263#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002265
Guido van Rossumb6775db1994-08-01 11:34:53 +00002266#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002267PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002268"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002269Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002270
Barry Warsaw53699e91996-12-10 23:23:01 +00002271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002272posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002273{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002274 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002276#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002280"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002281Return a list containing the names of the entries in the directory.\n\
2282\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002283 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002284\n\
2285The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002286entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002287
Barry Warsaw53699e91996-12-10 23:23:01 +00002288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002289posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002290{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002291 /* XXX Should redo this putting the (now four) versions of opendir
2292 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002293#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002294
Victor Stinnerd6f85422010-05-05 23:33:33 +00002295 PyObject *d, *v;
2296 HANDLE hFindFile;
2297 BOOL result;
2298 WIN32_FIND_DATA FileData;
2299 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2300 char *bufptr = namebuf;
2301 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002302
Victor Stinnerd6f85422010-05-05 23:33:33 +00002303 PyObject *po;
2304 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2305 WIN32_FIND_DATAW wFileData;
2306 Py_UNICODE *wnamebuf;
2307 /* Overallocate for \\*.*\0 */
2308 len = PyUnicode_GET_SIZE(po);
2309 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2310 if (!wnamebuf) {
2311 PyErr_NoMemory();
2312 return NULL;
2313 }
2314 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2315 if (len > 0) {
2316 Py_UNICODE wch = wnamebuf[len-1];
2317 if (wch != L'/' && wch != L'\\' && wch != L':')
2318 wnamebuf[len++] = L'\\';
2319 wcscpy(wnamebuf + len, L"*.*");
2320 }
2321 if ((d = PyList_New(0)) == NULL) {
2322 free(wnamebuf);
2323 return NULL;
2324 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002325 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002326 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002327 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002328 if (hFindFile == INVALID_HANDLE_VALUE) {
2329 int error = GetLastError();
2330 if (error == ERROR_FILE_NOT_FOUND) {
2331 free(wnamebuf);
2332 return d;
2333 }
2334 Py_DECREF(d);
2335 win32_error_unicode("FindFirstFileW", wnamebuf);
2336 free(wnamebuf);
2337 return NULL;
2338 }
2339 do {
2340 /* Skip over . and .. */
2341 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2342 wcscmp(wFileData.cFileName, L"..") != 0) {
2343 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2344 if (v == NULL) {
2345 Py_DECREF(d);
2346 d = NULL;
2347 break;
2348 }
2349 if (PyList_Append(d, v) != 0) {
2350 Py_DECREF(v);
2351 Py_DECREF(d);
2352 d = NULL;
2353 break;
2354 }
2355 Py_DECREF(v);
2356 }
2357 Py_BEGIN_ALLOW_THREADS
2358 result = FindNextFileW(hFindFile, &wFileData);
2359 Py_END_ALLOW_THREADS
2360 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2361 it got to the end of the directory. */
2362 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2363 Py_DECREF(d);
2364 win32_error_unicode("FindNextFileW", wnamebuf);
2365 FindClose(hFindFile);
2366 free(wnamebuf);
2367 return NULL;
2368 }
2369 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002370
Victor Stinnerd6f85422010-05-05 23:33:33 +00002371 if (FindClose(hFindFile) == FALSE) {
2372 Py_DECREF(d);
2373 win32_error_unicode("FindClose", wnamebuf);
2374 free(wnamebuf);
2375 return NULL;
2376 }
2377 free(wnamebuf);
2378 return d;
2379 }
2380 /* Drop the argument parsing error as narrow strings
2381 are also valid. */
2382 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002383
Victor Stinnerd6f85422010-05-05 23:33:33 +00002384 if (!PyArg_ParseTuple(args, "et#:listdir",
2385 Py_FileSystemDefaultEncoding, &bufptr, &len))
2386 return NULL;
2387 if (len > 0) {
2388 char ch = namebuf[len-1];
2389 if (ch != SEP && ch != ALTSEP && ch != ':')
2390 namebuf[len++] = '/';
2391 strcpy(namebuf + len, "*.*");
2392 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002393
Victor Stinnerd6f85422010-05-05 23:33:33 +00002394 if ((d = PyList_New(0)) == NULL)
2395 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002396
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002397 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002398 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002399 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002400 if (hFindFile == INVALID_HANDLE_VALUE) {
2401 int error = GetLastError();
2402 if (error == ERROR_FILE_NOT_FOUND)
2403 return d;
2404 Py_DECREF(d);
2405 return win32_error("FindFirstFile", namebuf);
2406 }
2407 do {
2408 /* Skip over . and .. */
2409 if (strcmp(FileData.cFileName, ".") != 0 &&
2410 strcmp(FileData.cFileName, "..") != 0) {
2411 v = PyString_FromString(FileData.cFileName);
2412 if (v == NULL) {
2413 Py_DECREF(d);
2414 d = NULL;
2415 break;
2416 }
2417 if (PyList_Append(d, v) != 0) {
2418 Py_DECREF(v);
2419 Py_DECREF(d);
2420 d = NULL;
2421 break;
2422 }
2423 Py_DECREF(v);
2424 }
2425 Py_BEGIN_ALLOW_THREADS
2426 result = FindNextFile(hFindFile, &FileData);
2427 Py_END_ALLOW_THREADS
2428 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2429 it got to the end of the directory. */
2430 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2431 Py_DECREF(d);
2432 win32_error("FindNextFile", namebuf);
2433 FindClose(hFindFile);
2434 return NULL;
2435 }
2436 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002437
Victor Stinnerd6f85422010-05-05 23:33:33 +00002438 if (FindClose(hFindFile) == FALSE) {
2439 Py_DECREF(d);
2440 return win32_error("FindClose", namebuf);
2441 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002442
Victor Stinnerd6f85422010-05-05 23:33:33 +00002443 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002444
Tim Peters0bb44a42000-09-15 07:44:49 +00002445#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002446
2447#ifndef MAX_PATH
2448#define MAX_PATH CCHMAXPATH
2449#endif
2450 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002451 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002452 PyObject *d, *v;
2453 char namebuf[MAX_PATH+5];
2454 HDIR hdir = 1;
2455 ULONG srchcnt = 1;
2456 FILEFINDBUF3 ep;
2457 APIRET rc;
2458
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002459 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002460 return NULL;
2461 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002462 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002463 return NULL;
2464 }
2465 strcpy(namebuf, name);
2466 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002467 if (*pt == ALTSEP)
2468 *pt = SEP;
2469 if (namebuf[len-1] != SEP)
2470 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002471 strcpy(namebuf + len, "*.*");
2472
Victor Stinnerd6f85422010-05-05 23:33:33 +00002473 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002474 return NULL;
2475
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002476 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2477 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002478 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002479 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2480 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2481 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002482
2483 if (rc != NO_ERROR) {
2484 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002485 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002486 }
2487
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002488 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002489 do {
2490 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002491 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002492 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002493
2494 strcpy(namebuf, ep.achName);
2495
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002496 /* Leave Case of Name Alone -- In Native Form */
2497 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002498
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002499 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002500 if (v == NULL) {
2501 Py_DECREF(d);
2502 d = NULL;
2503 break;
2504 }
2505 if (PyList_Append(d, v) != 0) {
2506 Py_DECREF(v);
2507 Py_DECREF(d);
2508 d = NULL;
2509 break;
2510 }
2511 Py_DECREF(v);
2512 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2513 }
2514
2515 return d;
2516#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002517
Victor Stinnerd6f85422010-05-05 23:33:33 +00002518 char *name = NULL;
2519 PyObject *d, *v;
2520 DIR *dirp;
2521 struct dirent *ep;
2522 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002523
Victor Stinnerd6f85422010-05-05 23:33:33 +00002524 errno = 0;
2525 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2526 arg_is_unicode = 0;
2527 PyErr_Clear();
2528 }
2529 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2530 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002531 Py_BEGIN_ALLOW_THREADS
2532 dirp = opendir(name);
2533 Py_END_ALLOW_THREADS
2534 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002535 return posix_error_with_allocated_filename(name);
2536 }
2537 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002538 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002539 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002540 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002541 PyMem_Free(name);
2542 return NULL;
2543 }
2544 for (;;) {
2545 errno = 0;
2546 Py_BEGIN_ALLOW_THREADS
2547 ep = readdir(dirp);
2548 Py_END_ALLOW_THREADS
2549 if (ep == NULL) {
2550 if (errno == 0) {
2551 break;
2552 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002553 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002554 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002555 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002556 Py_DECREF(d);
2557 return posix_error_with_allocated_filename(name);
2558 }
2559 }
2560 if (ep->d_name[0] == '.' &&
2561 (NAMLEN(ep) == 1 ||
2562 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2563 continue;
2564 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2565 if (v == NULL) {
2566 Py_DECREF(d);
2567 d = NULL;
2568 break;
2569 }
Just van Rossum46c97842003-02-25 21:42:15 +00002570#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002571 if (arg_is_unicode) {
2572 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002573
Victor Stinnerd6f85422010-05-05 23:33:33 +00002574 w = PyUnicode_FromEncodedObject(v,
2575 Py_FileSystemDefaultEncoding,
2576 "strict");
2577 if (w != NULL) {
2578 Py_DECREF(v);
2579 v = w;
2580 }
2581 else {
2582 /* fall back to the original byte string, as
2583 discussed in patch #683592 */
2584 PyErr_Clear();
2585 }
2586 }
Just van Rossum46c97842003-02-25 21:42:15 +00002587#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002588 if (PyList_Append(d, v) != 0) {
2589 Py_DECREF(v);
2590 Py_DECREF(d);
2591 d = NULL;
2592 break;
2593 }
2594 Py_DECREF(v);
2595 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002596 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002597 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002598 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002599 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002600
Victor Stinnerd6f85422010-05-05 23:33:33 +00002601 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002602
Tim Peters0bb44a42000-09-15 07:44:49 +00002603#endif /* which OS */
2604} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002605
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002606#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002607/* A helper function for abspath on win32 */
2608static PyObject *
2609posix__getfullpathname(PyObject *self, PyObject *args)
2610{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002611 /* assume encoded strings won't more than double no of chars */
2612 char inbuf[MAX_PATH*2];
2613 char *inbufp = inbuf;
2614 Py_ssize_t insize = sizeof(inbuf);
2615 char outbuf[MAX_PATH*2];
2616 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002617
Victor Stinnerd6f85422010-05-05 23:33:33 +00002618 PyUnicodeObject *po;
2619 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2620 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2621 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2622 Py_UNICODE *wtemp;
2623 DWORD result;
2624 PyObject *v;
2625 result = GetFullPathNameW(wpath,
2626 sizeof(woutbuf)/sizeof(woutbuf[0]),
2627 woutbuf, &wtemp);
2628 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2629 woutbufp = malloc(result * sizeof(Py_UNICODE));
2630 if (!woutbufp)
2631 return PyErr_NoMemory();
2632 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2633 }
2634 if (result)
2635 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2636 else
2637 v = win32_error_unicode("GetFullPathNameW", wpath);
2638 if (woutbufp != woutbuf)
2639 free(woutbufp);
2640 return v;
2641 }
2642 /* Drop the argument parsing error as narrow strings
2643 are also valid. */
2644 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002645
Victor Stinnerd6f85422010-05-05 23:33:33 +00002646 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2647 Py_FileSystemDefaultEncoding, &inbufp,
2648 &insize))
2649 return NULL;
2650 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2651 outbuf, &temp))
2652 return win32_error("GetFullPathName", inbuf);
2653 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2654 return PyUnicode_Decode(outbuf, strlen(outbuf),
2655 Py_FileSystemDefaultEncoding, NULL);
2656 }
2657 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002658} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002659#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002662"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002663Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002664
Barry Warsaw53699e91996-12-10 23:23:01 +00002665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002666posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002667{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002668 int res;
2669 char *path = NULL;
2670 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002671
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002672#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002673 PyUnicodeObject *po;
2674 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2675 Py_BEGIN_ALLOW_THREADS
2676 /* PyUnicode_AS_UNICODE OK without thread lock as
2677 it is a simple dereference. */
2678 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2679 Py_END_ALLOW_THREADS
2680 if (!res)
2681 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2682 Py_INCREF(Py_None);
2683 return Py_None;
2684 }
2685 /* Drop the argument parsing error as narrow strings
2686 are also valid. */
2687 PyErr_Clear();
2688 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2689 Py_FileSystemDefaultEncoding, &path, &mode))
2690 return NULL;
2691 Py_BEGIN_ALLOW_THREADS
2692 /* PyUnicode_AS_UNICODE OK without thread lock as
2693 it is a simple dereference. */
2694 res = CreateDirectoryA(path, NULL);
2695 Py_END_ALLOW_THREADS
2696 if (!res) {
2697 win32_error("mkdir", path);
2698 PyMem_Free(path);
2699 return NULL;
2700 }
2701 PyMem_Free(path);
2702 Py_INCREF(Py_None);
2703 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002704#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002705
Victor Stinnerd6f85422010-05-05 23:33:33 +00002706 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2707 Py_FileSystemDefaultEncoding, &path, &mode))
2708 return NULL;
2709 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002710#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002711 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002712#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002713 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002714#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002715 Py_END_ALLOW_THREADS
2716 if (res < 0)
2717 return posix_error_with_allocated_filename(path);
2718 PyMem_Free(path);
2719 Py_INCREF(Py_None);
2720 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002721#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002722}
2723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Neal Norwitz1818ed72006-03-26 00:29:48 +00002725/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2726#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002727#include <sys/resource.h>
2728#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002729
Neal Norwitz1818ed72006-03-26 00:29:48 +00002730
2731#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002732PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002733"nice(inc) -> new_priority\n\n\
2734Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002735
Barry Warsaw53699e91996-12-10 23:23:01 +00002736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002737posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002738{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002739 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002740
Victor Stinnerd6f85422010-05-05 23:33:33 +00002741 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2742 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002743
Victor Stinnerd6f85422010-05-05 23:33:33 +00002744 /* There are two flavours of 'nice': one that returns the new
2745 priority (as required by almost all standards out there) and the
2746 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2747 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002748
Victor Stinnerd6f85422010-05-05 23:33:33 +00002749 If we are of the nice family that returns the new priority, we
2750 need to clear errno before the call, and check if errno is filled
2751 before calling posix_error() on a returnvalue of -1, because the
2752 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002753
Victor Stinnerd6f85422010-05-05 23:33:33 +00002754 errno = 0;
2755 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002756#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002757 if (value == 0)
2758 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002759#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002760 if (value == -1 && errno != 0)
2761 /* either nice() or getpriority() returned an error */
2762 return posix_error();
2763 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002764}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002765#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002768"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Barry Warsaw53699e91996-12-10 23:23:01 +00002771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002772posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002773{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002774#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002775 PyObject *o1, *o2;
2776 char *p1, *p2;
2777 BOOL result;
2778 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2779 goto error;
2780 if (!convert_to_unicode(&o1))
2781 goto error;
2782 if (!convert_to_unicode(&o2)) {
2783 Py_DECREF(o1);
2784 goto error;
2785 }
2786 Py_BEGIN_ALLOW_THREADS
2787 result = MoveFileW(PyUnicode_AsUnicode(o1),
2788 PyUnicode_AsUnicode(o2));
2789 Py_END_ALLOW_THREADS
2790 Py_DECREF(o1);
2791 Py_DECREF(o2);
2792 if (!result)
2793 return win32_error("rename", NULL);
2794 Py_INCREF(Py_None);
2795 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002796error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002797 PyErr_Clear();
2798 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2799 return NULL;
2800 Py_BEGIN_ALLOW_THREADS
2801 result = MoveFileA(p1, p2);
2802 Py_END_ALLOW_THREADS
2803 if (!result)
2804 return win32_error("rename", NULL);
2805 Py_INCREF(Py_None);
2806 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002807#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002808 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002809#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002810}
2811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002812
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002813PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002814"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002815Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002816
Barry Warsaw53699e91996-12-10 23:23:01 +00002817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002818posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002819{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002820#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002821 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002822#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002823 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002824#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002825}
2826
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002827
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002828PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002829"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002830Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002831
Barry Warsaw53699e91996-12-10 23:23:01 +00002832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002833posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002835#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002836 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002837#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002838 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002839#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002840}
2841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002842
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002843#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002844PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002845"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002847
Barry Warsaw53699e91996-12-10 23:23:01 +00002848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002849posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002850{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002851 char *command;
2852 long sts;
2853 if (!PyArg_ParseTuple(args, "s:system", &command))
2854 return NULL;
2855 Py_BEGIN_ALLOW_THREADS
2856 sts = system(command);
2857 Py_END_ALLOW_THREADS
2858 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002859}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002860#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002863PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002864"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002865Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002866
Barry Warsaw53699e91996-12-10 23:23:01 +00002867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002868posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002870 int i;
2871 if (!PyArg_ParseTuple(args, "i:umask", &i))
2872 return NULL;
2873 i = (int)umask(i);
2874 if (i < 0)
2875 return posix_error();
2876 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002877}
2878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002879
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002881"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002882Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002884PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002885"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002887
Barry Warsaw53699e91996-12-10 23:23:01 +00002888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002889posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002891#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002892 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002893#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002894 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002895#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002896}
2897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002898
Guido van Rossumb6775db1994-08-01 11:34:53 +00002899#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002900PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002901"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002902Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903
Barry Warsaw53699e91996-12-10 23:23:01 +00002904static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002905posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002906{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002907 struct utsname u;
2908 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002909
Victor Stinnerd6f85422010-05-05 23:33:33 +00002910 Py_BEGIN_ALLOW_THREADS
2911 res = uname(&u);
2912 Py_END_ALLOW_THREADS
2913 if (res < 0)
2914 return posix_error();
2915 return Py_BuildValue("(sssss)",
2916 u.sysname,
2917 u.nodename,
2918 u.release,
2919 u.version,
2920 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002921}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002922#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002923
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002924static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002925extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002926{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002927 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002928 if (PyFloat_Check(t)) {
2929 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002930 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002931 if (!intobj)
2932 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002933#if SIZEOF_TIME_T > SIZEOF_LONG
2934 intval = PyInt_AsUnsignedLongLongMask(intobj);
2935#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002936 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002937#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002938 Py_DECREF(intobj);
2939 if (intval == -1 && PyErr_Occurred())
2940 return -1;
2941 *sec = intval;
2942 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2943 if (*usec < 0)
2944 /* If rounding gave us a negative number,
2945 truncate. */
2946 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002947 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002948 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002949#if SIZEOF_TIME_T > SIZEOF_LONG
2950 intval = PyInt_AsUnsignedLongLongMask(t);
2951#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002952 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002953#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002954 if (intval == -1 && PyErr_Occurred())
2955 return -1;
2956 *sec = intval;
2957 *usec = 0;
2958 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002959}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002962"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002963utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002964Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002965second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002966
Barry Warsaw53699e91996-12-10 23:23:01 +00002967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002968posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002969{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002970#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002971 PyObject *arg;
2972 PyUnicodeObject *obwpath;
2973 wchar_t *wpath = NULL;
2974 char *apath = NULL;
2975 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002976 time_t atimesec, mtimesec;
2977 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002978 FILETIME atime, mtime;
2979 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002980
Victor Stinnerd6f85422010-05-05 23:33:33 +00002981 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2982 wpath = PyUnicode_AS_UNICODE(obwpath);
2983 Py_BEGIN_ALLOW_THREADS
2984 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2985 NULL, OPEN_EXISTING,
2986 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2987 Py_END_ALLOW_THREADS
2988 if (hFile == INVALID_HANDLE_VALUE)
2989 return win32_error_unicode("utime", wpath);
2990 } else
2991 /* Drop the argument parsing error as narrow strings
2992 are also valid. */
2993 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002994
Victor Stinnerd6f85422010-05-05 23:33:33 +00002995 if (!wpath) {
2996 if (!PyArg_ParseTuple(args, "etO:utime",
2997 Py_FileSystemDefaultEncoding, &apath, &arg))
2998 return NULL;
2999 Py_BEGIN_ALLOW_THREADS
3000 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
3001 NULL, OPEN_EXISTING,
3002 FILE_FLAG_BACKUP_SEMANTICS, NULL);
3003 Py_END_ALLOW_THREADS
3004 if (hFile == INVALID_HANDLE_VALUE) {
3005 win32_error("utime", apath);
3006 PyMem_Free(apath);
3007 return NULL;
3008 }
3009 PyMem_Free(apath);
3010 }
3011
3012 if (arg == Py_None) {
3013 SYSTEMTIME now;
3014 GetSystemTime(&now);
3015 if (!SystemTimeToFileTime(&now, &mtime) ||
3016 !SystemTimeToFileTime(&now, &atime)) {
3017 win32_error("utime", NULL);
3018 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00003019 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003020 }
3021 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3022 PyErr_SetString(PyExc_TypeError,
3023 "utime() arg 2 must be a tuple (atime, mtime)");
3024 goto done;
3025 }
3026 else {
3027 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3028 &atimesec, &ausec) == -1)
3029 goto done;
3030 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3031 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3032 &mtimesec, &musec) == -1)
3033 goto done;
3034 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3035 }
3036 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3037 /* Avoid putting the file name into the error here,
3038 as that may confuse the user into believing that
3039 something is wrong with the file, when it also
3040 could be the time stamp that gives a problem. */
3041 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00003042 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003043 }
3044 Py_INCREF(Py_None);
3045 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003046done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003047 CloseHandle(hFile);
3048 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003049#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003050
Victor Stinnerd6f85422010-05-05 23:33:33 +00003051 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00003052 time_t atime, mtime;
3053 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003054 int res;
3055 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003056
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003057#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003058 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003059#define ATIME buf[0].tv_sec
3060#define MTIME buf[1].tv_sec
3061#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003062/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003063 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003064#define ATIME buf.actime
3065#define MTIME buf.modtime
3066#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003067#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003068 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003069#define ATIME buf[0]
3070#define MTIME buf[1]
3071#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003072#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003073
Mark Hammond817c9292003-12-03 01:22:38 +00003074
Victor Stinnerd6f85422010-05-05 23:33:33 +00003075 if (!PyArg_ParseTuple(args, "etO:utime",
3076 Py_FileSystemDefaultEncoding, &path, &arg))
3077 return NULL;
3078 if (arg == Py_None) {
3079 /* optional time values not given */
3080 Py_BEGIN_ALLOW_THREADS
3081 res = utime(path, NULL);
3082 Py_END_ALLOW_THREADS
3083 }
3084 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3085 PyErr_SetString(PyExc_TypeError,
3086 "utime() arg 2 must be a tuple (atime, mtime)");
3087 PyMem_Free(path);
3088 return NULL;
3089 }
3090 else {
3091 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3092 &atime, &ausec) == -1) {
3093 PyMem_Free(path);
3094 return NULL;
3095 }
3096 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3097 &mtime, &musec) == -1) {
3098 PyMem_Free(path);
3099 return NULL;
3100 }
3101 ATIME = atime;
3102 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003103#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00003104 buf[0].tv_usec = ausec;
3105 buf[1].tv_usec = musec;
3106 Py_BEGIN_ALLOW_THREADS
3107 res = utimes(path, buf);
3108 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003109#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003110 Py_BEGIN_ALLOW_THREADS
3111 res = utime(path, UTIME_ARG);
3112 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003113#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003114 }
3115 if (res < 0) {
3116 return posix_error_with_allocated_filename(path);
3117 }
3118 PyMem_Free(path);
3119 Py_INCREF(Py_None);
3120 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003121#undef UTIME_ARG
3122#undef ATIME
3123#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003124#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003125}
3126
Guido van Rossum85e3b011991-06-03 12:42:10 +00003127
Guido van Rossum3b066191991-06-04 19:40:25 +00003128/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003130PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003131"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003132Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003133
Barry Warsaw53699e91996-12-10 23:23:01 +00003134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003135posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003136{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003137 int sts;
3138 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3139 return NULL;
3140 _exit(sts);
3141 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003142}
3143
Martin v. Löwis114619e2002-10-07 06:44:21 +00003144#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3145static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003146free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003147{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003148 Py_ssize_t i;
3149 for (i = 0; i < count; i++)
3150 PyMem_Free(array[i]);
3151 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003152}
3153#endif
3154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003156#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003157PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003158"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003159Execute an executable path with arguments, replacing current process.\n\
3160\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003161 path: path of executable file\n\
3162 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Barry Warsaw53699e91996-12-10 23:23:01 +00003164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003165posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003166{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003167 char *path;
3168 PyObject *argv;
3169 char **argvlist;
3170 Py_ssize_t i, argc;
3171 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003172
Victor Stinnerd6f85422010-05-05 23:33:33 +00003173 /* execv has two arguments: (path, argv), where
3174 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003175
Victor Stinnerd6f85422010-05-05 23:33:33 +00003176 if (!PyArg_ParseTuple(args, "etO:execv",
3177 Py_FileSystemDefaultEncoding,
3178 &path, &argv))
3179 return NULL;
3180 if (PyList_Check(argv)) {
3181 argc = PyList_Size(argv);
3182 getitem = PyList_GetItem;
3183 }
3184 else if (PyTuple_Check(argv)) {
3185 argc = PyTuple_Size(argv);
3186 getitem = PyTuple_GetItem;
3187 }
3188 else {
3189 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3190 PyMem_Free(path);
3191 return NULL;
3192 }
3193 if (argc < 1) {
3194 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3195 PyMem_Free(path);
3196 return NULL;
3197 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003198
Victor Stinnerd6f85422010-05-05 23:33:33 +00003199 argvlist = PyMem_NEW(char *, argc+1);
3200 if (argvlist == NULL) {
3201 PyMem_Free(path);
3202 return PyErr_NoMemory();
3203 }
3204 for (i = 0; i < argc; i++) {
3205 if (!PyArg_Parse((*getitem)(argv, i), "et",
3206 Py_FileSystemDefaultEncoding,
3207 &argvlist[i])) {
3208 free_string_array(argvlist, i);
3209 PyErr_SetString(PyExc_TypeError,
3210 "execv() arg 2 must contain only strings");
3211 PyMem_Free(path);
3212 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003213
Victor Stinnerd6f85422010-05-05 23:33:33 +00003214 }
3215 }
3216 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003217
Victor Stinnerd6f85422010-05-05 23:33:33 +00003218 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003219
Victor Stinnerd6f85422010-05-05 23:33:33 +00003220 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003221
Victor Stinnerd6f85422010-05-05 23:33:33 +00003222 free_string_array(argvlist, argc);
3223 PyMem_Free(path);
3224 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003225}
3226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003227
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003228PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003229"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003230Execute a path with arguments and environment, replacing current process.\n\
3231\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003232 path: path of executable file\n\
3233 args: tuple or list of arguments\n\
3234 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003238{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003239 char *path;
3240 PyObject *argv, *env;
3241 char **argvlist;
3242 char **envlist;
3243 PyObject *key, *val, *keys=NULL, *vals=NULL;
3244 Py_ssize_t i, pos, argc, envc;
3245 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3246 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003247
Victor Stinnerd6f85422010-05-05 23:33:33 +00003248 /* execve has three arguments: (path, argv, env), where
3249 argv is a list or tuple of strings and env is a dictionary
3250 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003251
Victor Stinnerd6f85422010-05-05 23:33:33 +00003252 if (!PyArg_ParseTuple(args, "etOO:execve",
3253 Py_FileSystemDefaultEncoding,
3254 &path, &argv, &env))
3255 return NULL;
3256 if (PyList_Check(argv)) {
3257 argc = PyList_Size(argv);
3258 getitem = PyList_GetItem;
3259 }
3260 else if (PyTuple_Check(argv)) {
3261 argc = PyTuple_Size(argv);
3262 getitem = PyTuple_GetItem;
3263 }
3264 else {
3265 PyErr_SetString(PyExc_TypeError,
3266 "execve() arg 2 must be a tuple or list");
3267 goto fail_0;
3268 }
3269 if (!PyMapping_Check(env)) {
3270 PyErr_SetString(PyExc_TypeError,
3271 "execve() arg 3 must be a mapping object");
3272 goto fail_0;
3273 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003274
Victor Stinnerd6f85422010-05-05 23:33:33 +00003275 argvlist = PyMem_NEW(char *, argc+1);
3276 if (argvlist == NULL) {
3277 PyErr_NoMemory();
3278 goto fail_0;
3279 }
3280 for (i = 0; i < argc; i++) {
3281 if (!PyArg_Parse((*getitem)(argv, i),
3282 "et;execve() arg 2 must contain only strings",
3283 Py_FileSystemDefaultEncoding,
3284 &argvlist[i]))
3285 {
3286 lastarg = i;
3287 goto fail_1;
3288 }
3289 }
3290 lastarg = argc;
3291 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003292
Victor Stinnerd6f85422010-05-05 23:33:33 +00003293 i = PyMapping_Size(env);
3294 if (i < 0)
3295 goto fail_1;
3296 envlist = PyMem_NEW(char *, i + 1);
3297 if (envlist == NULL) {
3298 PyErr_NoMemory();
3299 goto fail_1;
3300 }
3301 envc = 0;
3302 keys = PyMapping_Keys(env);
3303 vals = PyMapping_Values(env);
3304 if (!keys || !vals)
3305 goto fail_2;
3306 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3307 PyErr_SetString(PyExc_TypeError,
3308 "execve(): env.keys() or env.values() is not a list");
3309 goto fail_2;
3310 }
Tim Peters5aa91602002-01-30 05:46:57 +00003311
Victor Stinnerd6f85422010-05-05 23:33:33 +00003312 for (pos = 0; pos < i; pos++) {
3313 char *p, *k, *v;
3314 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003315
Victor Stinnerd6f85422010-05-05 23:33:33 +00003316 key = PyList_GetItem(keys, pos);
3317 val = PyList_GetItem(vals, pos);
3318 if (!key || !val)
3319 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003320
Victor Stinnerd6f85422010-05-05 23:33:33 +00003321 if (!PyArg_Parse(
3322 key,
3323 "s;execve() arg 3 contains a non-string key",
3324 &k) ||
3325 !PyArg_Parse(
3326 val,
3327 "s;execve() arg 3 contains a non-string value",
3328 &v))
3329 {
3330 goto fail_2;
3331 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003332
3333#if defined(PYOS_OS2)
3334 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3335 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3336#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003337 len = PyString_Size(key) + PyString_Size(val) + 2;
3338 p = PyMem_NEW(char, len);
3339 if (p == NULL) {
3340 PyErr_NoMemory();
3341 goto fail_2;
3342 }
3343 PyOS_snprintf(p, len, "%s=%s", k, v);
3344 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003345#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003346 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003347#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003348 }
3349 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003350
Victor Stinnerd6f85422010-05-05 23:33:33 +00003351 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003352
Victor Stinnerd6f85422010-05-05 23:33:33 +00003353 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003354
Victor Stinnerd6f85422010-05-05 23:33:33 +00003355 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003356
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003357 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003358 while (--envc >= 0)
3359 PyMem_DEL(envlist[envc]);
3360 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003361 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003362 free_string_array(argvlist, lastarg);
3363 Py_XDECREF(vals);
3364 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003365 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003366 PyMem_Free(path);
3367 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003368}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003369#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003370
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Guido van Rossuma1065681999-01-25 23:20:23 +00003372#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003373PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003374"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003375Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003376\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003377 mode: mode of process creation\n\
3378 path: path of executable file\n\
3379 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003380
3381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003382posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003383{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003384 char *path;
3385 PyObject *argv;
3386 char **argvlist;
3387 int mode, i;
3388 Py_ssize_t argc;
3389 Py_intptr_t spawnval;
3390 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003391
Victor Stinnerd6f85422010-05-05 23:33:33 +00003392 /* spawnv has three arguments: (mode, path, argv), where
3393 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003394
Victor Stinnerd6f85422010-05-05 23:33:33 +00003395 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3396 Py_FileSystemDefaultEncoding,
3397 &path, &argv))
3398 return NULL;
3399 if (PyList_Check(argv)) {
3400 argc = PyList_Size(argv);
3401 getitem = PyList_GetItem;
3402 }
3403 else if (PyTuple_Check(argv)) {
3404 argc = PyTuple_Size(argv);
3405 getitem = PyTuple_GetItem;
3406 }
3407 else {
3408 PyErr_SetString(PyExc_TypeError,
3409 "spawnv() arg 2 must be a tuple or list");
3410 PyMem_Free(path);
3411 return NULL;
3412 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003413
Victor Stinnerd6f85422010-05-05 23:33:33 +00003414 argvlist = PyMem_NEW(char *, argc+1);
3415 if (argvlist == NULL) {
3416 PyMem_Free(path);
3417 return PyErr_NoMemory();
3418 }
3419 for (i = 0; i < argc; i++) {
3420 if (!PyArg_Parse((*getitem)(argv, i), "et",
3421 Py_FileSystemDefaultEncoding,
3422 &argvlist[i])) {
3423 free_string_array(argvlist, i);
3424 PyErr_SetString(
3425 PyExc_TypeError,
3426 "spawnv() arg 2 must contain only strings");
3427 PyMem_Free(path);
3428 return NULL;
3429 }
3430 }
3431 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003432
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003433#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003434 Py_BEGIN_ALLOW_THREADS
3435 spawnval = spawnv(mode, path, argvlist);
3436 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003437#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003438 if (mode == _OLD_P_OVERLAY)
3439 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003440
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 Py_BEGIN_ALLOW_THREADS
3442 spawnval = _spawnv(mode, path, argvlist);
3443 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003444#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003445
Victor Stinnerd6f85422010-05-05 23:33:33 +00003446 free_string_array(argvlist, argc);
3447 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003448
Victor Stinnerd6f85422010-05-05 23:33:33 +00003449 if (spawnval == -1)
3450 return posix_error();
3451 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003452#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003453 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003454#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003455 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003456#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003457}
3458
3459
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003460PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003461"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003462Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003463\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003464 mode: mode of process creation\n\
3465 path: path of executable file\n\
3466 args: tuple or list of arguments\n\
3467 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003468
3469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003470posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003471{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003472 char *path;
3473 PyObject *argv, *env;
3474 char **argvlist;
3475 char **envlist;
3476 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3477 int mode, pos, envc;
3478 Py_ssize_t argc, i;
3479 Py_intptr_t spawnval;
3480 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3481 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003482
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 /* spawnve has four arguments: (mode, path, argv, env), where
3484 argv is a list or tuple of strings and env is a dictionary
3485 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003486
Victor Stinnerd6f85422010-05-05 23:33:33 +00003487 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3488 Py_FileSystemDefaultEncoding,
3489 &path, &argv, &env))
3490 return NULL;
3491 if (PyList_Check(argv)) {
3492 argc = PyList_Size(argv);
3493 getitem = PyList_GetItem;
3494 }
3495 else if (PyTuple_Check(argv)) {
3496 argc = PyTuple_Size(argv);
3497 getitem = PyTuple_GetItem;
3498 }
3499 else {
3500 PyErr_SetString(PyExc_TypeError,
3501 "spawnve() arg 2 must be a tuple or list");
3502 goto fail_0;
3503 }
3504 if (!PyMapping_Check(env)) {
3505 PyErr_SetString(PyExc_TypeError,
3506 "spawnve() arg 3 must be a mapping object");
3507 goto fail_0;
3508 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003509
Victor Stinnerd6f85422010-05-05 23:33:33 +00003510 argvlist = PyMem_NEW(char *, argc+1);
3511 if (argvlist == NULL) {
3512 PyErr_NoMemory();
3513 goto fail_0;
3514 }
3515 for (i = 0; i < argc; i++) {
3516 if (!PyArg_Parse((*getitem)(argv, i),
3517 "et;spawnve() arg 2 must contain only strings",
3518 Py_FileSystemDefaultEncoding,
3519 &argvlist[i]))
3520 {
3521 lastarg = i;
3522 goto fail_1;
3523 }
3524 }
3525 lastarg = argc;
3526 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003527
Victor Stinnerd6f85422010-05-05 23:33:33 +00003528 i = PyMapping_Size(env);
3529 if (i < 0)
3530 goto fail_1;
3531 envlist = PyMem_NEW(char *, i + 1);
3532 if (envlist == NULL) {
3533 PyErr_NoMemory();
3534 goto fail_1;
3535 }
3536 envc = 0;
3537 keys = PyMapping_Keys(env);
3538 vals = PyMapping_Values(env);
3539 if (!keys || !vals)
3540 goto fail_2;
3541 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3542 PyErr_SetString(PyExc_TypeError,
3543 "spawnve(): env.keys() or env.values() is not a list");
3544 goto fail_2;
3545 }
Tim Peters5aa91602002-01-30 05:46:57 +00003546
Victor Stinnerd6f85422010-05-05 23:33:33 +00003547 for (pos = 0; pos < i; pos++) {
3548 char *p, *k, *v;
3549 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003550
Victor Stinnerd6f85422010-05-05 23:33:33 +00003551 key = PyList_GetItem(keys, pos);
3552 val = PyList_GetItem(vals, pos);
3553 if (!key || !val)
3554 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003555
Victor Stinnerd6f85422010-05-05 23:33:33 +00003556 if (!PyArg_Parse(
3557 key,
3558 "s;spawnve() arg 3 contains a non-string key",
3559 &k) ||
3560 !PyArg_Parse(
3561 val,
3562 "s;spawnve() arg 3 contains a non-string value",
3563 &v))
3564 {
3565 goto fail_2;
3566 }
3567 len = PyString_Size(key) + PyString_Size(val) + 2;
3568 p = PyMem_NEW(char, len);
3569 if (p == NULL) {
3570 PyErr_NoMemory();
3571 goto fail_2;
3572 }
3573 PyOS_snprintf(p, len, "%s=%s", k, v);
3574 envlist[envc++] = p;
3575 }
3576 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003577
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003578#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003579 Py_BEGIN_ALLOW_THREADS
3580 spawnval = spawnve(mode, path, argvlist, envlist);
3581 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003582#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003583 if (mode == _OLD_P_OVERLAY)
3584 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003585
Victor Stinnerd6f85422010-05-05 23:33:33 +00003586 Py_BEGIN_ALLOW_THREADS
3587 spawnval = _spawnve(mode, path, argvlist, envlist);
3588 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003589#endif
Tim Peters25059d32001-12-07 20:35:43 +00003590
Victor Stinnerd6f85422010-05-05 23:33:33 +00003591 if (spawnval == -1)
3592 (void) posix_error();
3593 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003594#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003596#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003597 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003598#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003599
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003600 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003601 while (--envc >= 0)
3602 PyMem_DEL(envlist[envc]);
3603 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003604 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003605 free_string_array(argvlist, lastarg);
3606 Py_XDECREF(vals);
3607 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003608 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003609 PyMem_Free(path);
3610 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003611}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003612
3613/* OS/2 supports spawnvp & spawnvpe natively */
3614#if defined(PYOS_OS2)
3615PyDoc_STRVAR(posix_spawnvp__doc__,
3616"spawnvp(mode, file, args)\n\n\
3617Execute the program 'file' in a new process, using the environment\n\
3618search path to find the file.\n\
3619\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003620 mode: mode of process creation\n\
3621 file: executable file name\n\
3622 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003623
3624static PyObject *
3625posix_spawnvp(PyObject *self, PyObject *args)
3626{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003627 char *path;
3628 PyObject *argv;
3629 char **argvlist;
3630 int mode, i, argc;
3631 Py_intptr_t spawnval;
3632 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003633
Victor Stinnerd6f85422010-05-05 23:33:33 +00003634 /* spawnvp has three arguments: (mode, path, argv), where
3635 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003636
Victor Stinnerd6f85422010-05-05 23:33:33 +00003637 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3638 Py_FileSystemDefaultEncoding,
3639 &path, &argv))
3640 return NULL;
3641 if (PyList_Check(argv)) {
3642 argc = PyList_Size(argv);
3643 getitem = PyList_GetItem;
3644 }
3645 else if (PyTuple_Check(argv)) {
3646 argc = PyTuple_Size(argv);
3647 getitem = PyTuple_GetItem;
3648 }
3649 else {
3650 PyErr_SetString(PyExc_TypeError,
3651 "spawnvp() arg 2 must be a tuple or list");
3652 PyMem_Free(path);
3653 return NULL;
3654 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003655
Victor Stinnerd6f85422010-05-05 23:33:33 +00003656 argvlist = PyMem_NEW(char *, argc+1);
3657 if (argvlist == NULL) {
3658 PyMem_Free(path);
3659 return PyErr_NoMemory();
3660 }
3661 for (i = 0; i < argc; i++) {
3662 if (!PyArg_Parse((*getitem)(argv, i), "et",
3663 Py_FileSystemDefaultEncoding,
3664 &argvlist[i])) {
3665 free_string_array(argvlist, i);
3666 PyErr_SetString(
3667 PyExc_TypeError,
3668 "spawnvp() arg 2 must contain only strings");
3669 PyMem_Free(path);
3670 return NULL;
3671 }
3672 }
3673 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003674
Victor Stinnerd6f85422010-05-05 23:33:33 +00003675 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003676#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003677 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003678#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003679 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003680#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003681 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003682
Victor Stinnerd6f85422010-05-05 23:33:33 +00003683 free_string_array(argvlist, argc);
3684 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003685
Victor Stinnerd6f85422010-05-05 23:33:33 +00003686 if (spawnval == -1)
3687 return posix_error();
3688 else
3689 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003690}
3691
3692
3693PyDoc_STRVAR(posix_spawnvpe__doc__,
3694"spawnvpe(mode, file, args, env)\n\n\
3695Execute the program 'file' in a new process, using the environment\n\
3696search path to find the file.\n\
3697\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003698 mode: mode of process creation\n\
3699 file: executable file name\n\
3700 args: tuple or list of arguments\n\
3701 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003702
3703static PyObject *
3704posix_spawnvpe(PyObject *self, PyObject *args)
3705{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003706 char *path;
3707 PyObject *argv, *env;
3708 char **argvlist;
3709 char **envlist;
3710 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3711 int mode, i, pos, argc, envc;
3712 Py_intptr_t spawnval;
3713 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3714 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003715
Victor Stinnerd6f85422010-05-05 23:33:33 +00003716 /* spawnvpe has four arguments: (mode, path, argv, env), where
3717 argv is a list or tuple of strings and env is a dictionary
3718 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003719
Victor Stinnerd6f85422010-05-05 23:33:33 +00003720 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3721 Py_FileSystemDefaultEncoding,
3722 &path, &argv, &env))
3723 return NULL;
3724 if (PyList_Check(argv)) {
3725 argc = PyList_Size(argv);
3726 getitem = PyList_GetItem;
3727 }
3728 else if (PyTuple_Check(argv)) {
3729 argc = PyTuple_Size(argv);
3730 getitem = PyTuple_GetItem;
3731 }
3732 else {
3733 PyErr_SetString(PyExc_TypeError,
3734 "spawnvpe() arg 2 must be a tuple or list");
3735 goto fail_0;
3736 }
3737 if (!PyMapping_Check(env)) {
3738 PyErr_SetString(PyExc_TypeError,
3739 "spawnvpe() arg 3 must be a mapping object");
3740 goto fail_0;
3741 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003742
Victor Stinnerd6f85422010-05-05 23:33:33 +00003743 argvlist = PyMem_NEW(char *, argc+1);
3744 if (argvlist == NULL) {
3745 PyErr_NoMemory();
3746 goto fail_0;
3747 }
3748 for (i = 0; i < argc; i++) {
3749 if (!PyArg_Parse((*getitem)(argv, i),
3750 "et;spawnvpe() arg 2 must contain only strings",
3751 Py_FileSystemDefaultEncoding,
3752 &argvlist[i]))
3753 {
3754 lastarg = i;
3755 goto fail_1;
3756 }
3757 }
3758 lastarg = argc;
3759 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003760
Victor Stinnerd6f85422010-05-05 23:33:33 +00003761 i = PyMapping_Size(env);
3762 if (i < 0)
3763 goto fail_1;
3764 envlist = PyMem_NEW(char *, i + 1);
3765 if (envlist == NULL) {
3766 PyErr_NoMemory();
3767 goto fail_1;
3768 }
3769 envc = 0;
3770 keys = PyMapping_Keys(env);
3771 vals = PyMapping_Values(env);
3772 if (!keys || !vals)
3773 goto fail_2;
3774 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3775 PyErr_SetString(PyExc_TypeError,
3776 "spawnvpe(): env.keys() or env.values() is not a list");
3777 goto fail_2;
3778 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003779
Victor Stinnerd6f85422010-05-05 23:33:33 +00003780 for (pos = 0; pos < i; pos++) {
3781 char *p, *k, *v;
3782 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003783
Victor Stinnerd6f85422010-05-05 23:33:33 +00003784 key = PyList_GetItem(keys, pos);
3785 val = PyList_GetItem(vals, pos);
3786 if (!key || !val)
3787 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003788
Victor Stinnerd6f85422010-05-05 23:33:33 +00003789 if (!PyArg_Parse(
3790 key,
3791 "s;spawnvpe() arg 3 contains a non-string key",
3792 &k) ||
3793 !PyArg_Parse(
3794 val,
3795 "s;spawnvpe() arg 3 contains a non-string value",
3796 &v))
3797 {
3798 goto fail_2;
3799 }
3800 len = PyString_Size(key) + PyString_Size(val) + 2;
3801 p = PyMem_NEW(char, len);
3802 if (p == NULL) {
3803 PyErr_NoMemory();
3804 goto fail_2;
3805 }
3806 PyOS_snprintf(p, len, "%s=%s", k, v);
3807 envlist[envc++] = p;
3808 }
3809 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003810
Victor Stinnerd6f85422010-05-05 23:33:33 +00003811 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003812#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003813 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003814#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003815 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003816#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003817 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818
Victor Stinnerd6f85422010-05-05 23:33:33 +00003819 if (spawnval == -1)
3820 (void) posix_error();
3821 else
3822 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003823
3824 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003825 while (--envc >= 0)
3826 PyMem_DEL(envlist[envc]);
3827 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003828 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003829 free_string_array(argvlist, lastarg);
3830 Py_XDECREF(vals);
3831 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003832 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003833 PyMem_Free(path);
3834 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003835}
3836#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003837#endif /* HAVE_SPAWNV */
3838
3839
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003840#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003842"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003843Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3844\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003845Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003846
3847static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003848posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003849{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003850 pid_t pid;
3851 int result = 0;
3852 _PyImport_AcquireLock();
3853 pid = fork1();
3854 if (pid == 0) {
3855 /* child: this clobbers and resets the import lock. */
3856 PyOS_AfterFork();
3857 } else {
3858 /* parent: release the import lock. */
3859 result = _PyImport_ReleaseLock();
3860 }
3861 if (pid == -1)
3862 return posix_error();
3863 if (result < 0) {
3864 /* Don't clobber the OSError if the fork failed. */
3865 PyErr_SetString(PyExc_RuntimeError,
3866 "not holding the import lock");
3867 return NULL;
3868 }
3869 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003870}
3871#endif
3872
3873
Guido van Rossumad0ee831995-03-01 10:34:45 +00003874#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003876"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003877Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003878Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003879
Barry Warsaw53699e91996-12-10 23:23:01 +00003880static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003881posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003882{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003883 pid_t pid;
3884 int result = 0;
3885 _PyImport_AcquireLock();
3886 pid = fork();
3887 if (pid == 0) {
3888 /* child: this clobbers and resets the import lock. */
3889 PyOS_AfterFork();
3890 } else {
3891 /* parent: release the import lock. */
3892 result = _PyImport_ReleaseLock();
3893 }
3894 if (pid == -1)
3895 return posix_error();
3896 if (result < 0) {
3897 /* Don't clobber the OSError if the fork failed. */
3898 PyErr_SetString(PyExc_RuntimeError,
3899 "not holding the import lock");
3900 return NULL;
3901 }
3902 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003903}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003904#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003905
Neal Norwitzb59798b2003-03-21 01:43:31 +00003906/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003907/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3908#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003909#define DEV_PTY_FILE "/dev/ptc"
3910#define HAVE_DEV_PTMX
3911#else
3912#define DEV_PTY_FILE "/dev/ptmx"
3913#endif
3914
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003915#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003916#ifdef HAVE_PTY_H
3917#include <pty.h>
3918#else
3919#ifdef HAVE_LIBUTIL_H
3920#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003921#else
3922#ifdef HAVE_UTIL_H
3923#include <util.h>
3924#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003925#endif /* HAVE_LIBUTIL_H */
3926#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003927#ifdef HAVE_STROPTS_H
3928#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003929#endif
3930#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003931
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003932#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003933PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003934"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003936
3937static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003938posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003939{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003940 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003941#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003942 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003943#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003944#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003945 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003946#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003947 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003948#endif
3949#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003950
Thomas Wouters70c21a12000-07-14 14:28:33 +00003951#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003952 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3953 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003954#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003955 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3956 if (slave_name == NULL)
3957 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003958
Victor Stinnerd6f85422010-05-05 23:33:33 +00003959 slave_fd = open(slave_name, O_RDWR);
3960 if (slave_fd < 0)
3961 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003962#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003963 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3964 if (master_fd < 0)
3965 return posix_error();
3966 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3967 /* change permission of slave */
3968 if (grantpt(master_fd) < 0) {
3969 PyOS_setsig(SIGCHLD, sig_saved);
3970 return posix_error();
3971 }
3972 /* unlock slave */
3973 if (unlockpt(master_fd) < 0) {
3974 PyOS_setsig(SIGCHLD, sig_saved);
3975 return posix_error();
3976 }
3977 PyOS_setsig(SIGCHLD, sig_saved);
3978 slave_name = ptsname(master_fd); /* get name of slave */
3979 if (slave_name == NULL)
3980 return posix_error();
3981 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3982 if (slave_fd < 0)
3983 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003984#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003985 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3986 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003987#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003988 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003989#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003990#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003991#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003992
Victor Stinnerd6f85422010-05-05 23:33:33 +00003993 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003994
Fred Drake8cef4cf2000-06-28 16:40:38 +00003995}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003996#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003997
3998#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003999PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004000"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004001Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4002Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004004
4005static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004006posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004007{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004008 int master_fd = -1, result = 0;
4009 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004010
Victor Stinnerd6f85422010-05-05 23:33:33 +00004011 _PyImport_AcquireLock();
4012 pid = forkpty(&master_fd, NULL, NULL, NULL);
4013 if (pid == 0) {
4014 /* child: this clobbers and resets the import lock. */
4015 PyOS_AfterFork();
4016 } else {
4017 /* parent: release the import lock. */
4018 result = _PyImport_ReleaseLock();
4019 }
4020 if (pid == -1)
4021 return posix_error();
4022 if (result < 0) {
4023 /* Don't clobber the OSError if the fork failed. */
4024 PyErr_SetString(PyExc_RuntimeError,
4025 "not holding the import lock");
4026 return NULL;
4027 }
4028 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004029}
4030#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004031
Guido van Rossumad0ee831995-03-01 10:34:45 +00004032#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004033PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004034"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004035Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036
Barry Warsaw53699e91996-12-10 23:23:01 +00004037static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004038posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004039{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004040 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004041}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004042#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004044
Guido van Rossumad0ee831995-03-01 10:34:45 +00004045#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004047"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004048Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Barry Warsaw53699e91996-12-10 23:23:01 +00004050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004051posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004052{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004053 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004054}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004055#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
Guido van Rossumad0ee831995-03-01 10:34:45 +00004058#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004060"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004062
Barry Warsaw53699e91996-12-10 23:23:01 +00004063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004064posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004065{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004066 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004067}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004068#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004071PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004072"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004073Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Barry Warsaw53699e91996-12-10 23:23:01 +00004075static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004076posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004077{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004078 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004079}
4080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
Fred Drakec9680921999-12-13 16:37:25 +00004082#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004083PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004084"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004086
4087static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004088posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004089{
4090 PyObject *result = NULL;
4091
Fred Drakec9680921999-12-13 16:37:25 +00004092#ifdef NGROUPS_MAX
4093#define MAX_GROUPS NGROUPS_MAX
4094#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004095 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004096#define MAX_GROUPS 64
4097#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004098 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004099
Victor Stinner59729ff2011-07-05 11:28:19 +02004100 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004101 * This is a helper variable to store the intermediate result when
4102 * that happens.
4103 *
4104 * To keep the code readable the OSX behaviour is unconditional,
4105 * according to the POSIX spec this should be safe on all unix-y
4106 * systems.
4107 */
4108 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004109 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004110
Ned Deily80743642013-08-01 21:19:09 -07004111#ifdef __APPLE__
4112 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4113 * there are more groups than can fit in grouplist. Therefore, on OS X
4114 * always first call getgroups with length 0 to get the actual number
4115 * of groups.
4116 */
4117 n = getgroups(0, NULL);
4118 if (n < 0) {
4119 return posix_error();
4120 } else if (n <= MAX_GROUPS) {
4121 /* groups will fit in existing array */
4122 alt_grouplist = grouplist;
4123 } else {
4124 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4125 if (alt_grouplist == NULL) {
4126 errno = EINVAL;
4127 return posix_error();
4128 }
4129 }
4130
4131 n = getgroups(n, alt_grouplist);
4132 if (n == -1) {
4133 if (alt_grouplist != grouplist) {
4134 PyMem_Free(alt_grouplist);
4135 }
4136 return posix_error();
4137 }
4138#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004139 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004140 if (n < 0) {
4141 if (errno == EINVAL) {
4142 n = getgroups(0, NULL);
4143 if (n == -1) {
4144 return posix_error();
4145 }
4146 if (n == 0) {
4147 /* Avoid malloc(0) */
4148 alt_grouplist = grouplist;
4149 } else {
4150 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4151 if (alt_grouplist == NULL) {
4152 errno = EINVAL;
4153 return posix_error();
4154 }
4155 n = getgroups(n, alt_grouplist);
4156 if (n == -1) {
4157 PyMem_Free(alt_grouplist);
4158 return posix_error();
4159 }
4160 }
4161 } else {
4162 return posix_error();
4163 }
4164 }
Ned Deily80743642013-08-01 21:19:09 -07004165#endif
4166
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004167 result = PyList_New(n);
4168 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 int i;
4170 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004171 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004172 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004173 Py_DECREF(result);
4174 result = NULL;
4175 break;
Fred Drakec9680921999-12-13 16:37:25 +00004176 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004177 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004178 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004179 }
4180
4181 if (alt_grouplist != grouplist) {
4182 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004183 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004184
Fred Drakec9680921999-12-13 16:37:25 +00004185 return result;
4186}
4187#endif
4188
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004189#ifdef HAVE_INITGROUPS
4190PyDoc_STRVAR(posix_initgroups__doc__,
4191"initgroups(username, gid) -> None\n\n\
4192Call the system initgroups() to initialize the group access list with all of\n\
4193the groups of which the specified username is a member, plus the specified\n\
4194group id.");
4195
4196static PyObject *
4197posix_initgroups(PyObject *self, PyObject *args)
4198{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004199 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004200#ifdef __APPLE__
4201 int gid;
4202#else
4203 gid_t gid;
4204#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004205
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004206#ifdef __APPLE__
4207 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4208 &gid))
4209#else
4210 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4211 _Py_Gid_Converter, &gid))
4212#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004213 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004214
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004215 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004216 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004217
Victor Stinnerd6f85422010-05-05 23:33:33 +00004218 Py_INCREF(Py_None);
4219 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004220}
4221#endif
4222
Martin v. Löwis606edc12002-06-13 21:09:11 +00004223#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004224PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004225"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004226Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004227
4228static PyObject *
4229posix_getpgid(PyObject *self, PyObject *args)
4230{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004231 pid_t pid, pgid;
4232 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4233 return NULL;
4234 pgid = getpgid(pid);
4235 if (pgid < 0)
4236 return posix_error();
4237 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004238}
4239#endif /* HAVE_GETPGID */
4240
4241
Guido van Rossumb6775db1994-08-01 11:34:53 +00004242#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004244"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004246
Barry Warsaw53699e91996-12-10 23:23:01 +00004247static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004248posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004249{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004250#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004251 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004252#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004253 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004254#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004255}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004256#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Guido van Rossumb6775db1994-08-01 11:34:53 +00004259#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004260PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004261"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004262Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004263
Barry Warsaw53699e91996-12-10 23:23:01 +00004264static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004265posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004266{
Guido van Rossum64933891994-10-20 21:56:42 +00004267#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004268 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004269#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004270 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004271#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004272 return posix_error();
4273 Py_INCREF(Py_None);
4274 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004275}
4276
Guido van Rossumb6775db1994-08-01 11:34:53 +00004277#endif /* HAVE_SETPGRP */
4278
Guido van Rossumad0ee831995-03-01 10:34:45 +00004279#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004280PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004281"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004285posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004286{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004287 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004288}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004289#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004291
Fred Drake12c6e2d1999-12-14 21:25:03 +00004292#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004293PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004294"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004295Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004296
4297static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004298posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004299{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004300 PyObject *result = NULL;
4301 char *name;
4302 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004303
Victor Stinnerd6f85422010-05-05 23:33:33 +00004304 errno = 0;
4305 name = getlogin();
4306 if (name == NULL) {
4307 if (errno)
4308 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004309 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004310 PyErr_SetString(PyExc_OSError,
4311 "unable to determine login name");
4312 }
4313 else
4314 result = PyString_FromString(name);
4315 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004316
Fred Drake12c6e2d1999-12-14 21:25:03 +00004317 return result;
4318}
4319#endif
4320
Guido van Rossumad0ee831995-03-01 10:34:45 +00004321#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004322PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004323"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Barry Warsaw53699e91996-12-10 23:23:01 +00004326static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004327posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004328{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004329 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004330}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004331#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004333
Guido van Rossumad0ee831995-03-01 10:34:45 +00004334#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004336"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004337Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004338
Barry Warsaw53699e91996-12-10 23:23:01 +00004339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004340posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004341{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004342 pid_t pid;
4343 int sig;
4344 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4345 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004346#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004347 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4348 APIRET rc;
4349 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004350 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004351
4352 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4353 APIRET rc;
4354 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004355 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004356
4357 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004358 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004359#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004360 if (kill(pid, sig) == -1)
4361 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004362#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004363 Py_INCREF(Py_None);
4364 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004365}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004366#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004367
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004368#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004369PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004370"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004371Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004372
4373static PyObject *
4374posix_killpg(PyObject *self, PyObject *args)
4375{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004376 int sig;
4377 pid_t pgid;
4378 /* XXX some man pages make the `pgid` parameter an int, others
4379 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4380 take the same type. Moreover, pid_t is always at least as wide as
4381 int (else compilation of this module fails), which is safe. */
4382 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4383 return NULL;
4384 if (killpg(pgid, sig) == -1)
4385 return posix_error();
4386 Py_INCREF(Py_None);
4387 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004388}
4389#endif
4390
Brian Curtine5aa8862010-04-02 23:26:06 +00004391#ifdef MS_WINDOWS
4392PyDoc_STRVAR(win32_kill__doc__,
4393"kill(pid, sig)\n\n\
4394Kill a process with a signal.");
4395
4396static PyObject *
4397win32_kill(PyObject *self, PyObject *args)
4398{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004399 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004400 DWORD pid, sig, err;
4401 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004402
Victor Stinnerd6f85422010-05-05 23:33:33 +00004403 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4404 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004405
Victor Stinnerd6f85422010-05-05 23:33:33 +00004406 /* Console processes which share a common console can be sent CTRL+C or
4407 CTRL+BREAK events, provided they handle said events. */
4408 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4409 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4410 err = GetLastError();
4411 return PyErr_SetFromWindowsErr(err);
4412 }
4413 else
4414 Py_RETURN_NONE;
4415 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004416
Victor Stinnerd6f85422010-05-05 23:33:33 +00004417 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4418 attempt to open and terminate the process. */
4419 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4420 if (handle == NULL) {
4421 err = GetLastError();
4422 return PyErr_SetFromWindowsErr(err);
4423 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004424
Victor Stinnerd6f85422010-05-05 23:33:33 +00004425 if (TerminateProcess(handle, sig) == 0) {
4426 err = GetLastError();
4427 result = PyErr_SetFromWindowsErr(err);
4428 } else {
4429 Py_INCREF(Py_None);
4430 result = Py_None;
4431 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004432
Victor Stinnerd6f85422010-05-05 23:33:33 +00004433 CloseHandle(handle);
4434 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004435}
Brian Curtincaea7e82011-06-08 19:29:53 -05004436
Brian Curtin5446f082011-06-09 10:00:42 -05004437PyDoc_STRVAR(posix__isdir__doc__,
4438"Return true if the pathname refers to an existing directory.");
4439
Brian Curtincaea7e82011-06-08 19:29:53 -05004440static PyObject *
4441posix__isdir(PyObject *self, PyObject *args)
4442{
4443 PyObject *opath;
4444 char *path;
4445 PyUnicodeObject *po;
4446 DWORD attributes;
4447
4448 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
4449 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
4450
4451 attributes = GetFileAttributesW(wpath);
4452 if (attributes == INVALID_FILE_ATTRIBUTES)
4453 Py_RETURN_FALSE;
4454 goto check;
4455 }
4456 /* Drop the argument parsing error as narrow strings
4457 are also valid. */
4458 PyErr_Clear();
4459
4460 if (!PyArg_ParseTuple(args, "et:_isdir",
4461 Py_FileSystemDefaultEncoding, &path))
4462 return NULL;
4463
4464 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004465 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004466 if (attributes == INVALID_FILE_ATTRIBUTES)
4467 Py_RETURN_FALSE;
4468
4469check:
4470 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4471 Py_RETURN_TRUE;
4472 else
4473 Py_RETURN_FALSE;
4474}
Brian Curtine5aa8862010-04-02 23:26:06 +00004475#endif /* MS_WINDOWS */
4476
Guido van Rossumc0125471996-06-28 18:55:32 +00004477#ifdef HAVE_PLOCK
4478
4479#ifdef HAVE_SYS_LOCK_H
4480#include <sys/lock.h>
4481#endif
4482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004483PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004484"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004485Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004486
Barry Warsaw53699e91996-12-10 23:23:01 +00004487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004488posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004489{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004490 int op;
4491 if (!PyArg_ParseTuple(args, "i:plock", &op))
4492 return NULL;
4493 if (plock(op) == -1)
4494 return posix_error();
4495 Py_INCREF(Py_None);
4496 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004497}
4498#endif
4499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004500
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004501#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004502PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004503"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004505
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004506#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004507#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004508static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004509async_system(const char *command)
4510{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004511 char errormsg[256], args[1024];
4512 RESULTCODES rcodes;
4513 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004514
Victor Stinnerd6f85422010-05-05 23:33:33 +00004515 char *shell = getenv("COMSPEC");
4516 if (!shell)
4517 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004518
Victor Stinnerd6f85422010-05-05 23:33:33 +00004519 /* avoid overflowing the argument buffer */
4520 if (strlen(shell) + 3 + strlen(command) >= 1024)
4521 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004522
Victor Stinnerd6f85422010-05-05 23:33:33 +00004523 args[0] = '\0';
4524 strcat(args, shell);
4525 strcat(args, "/c ");
4526 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004527
Victor Stinnerd6f85422010-05-05 23:33:33 +00004528 /* execute asynchronously, inheriting the environment */
4529 rc = DosExecPgm(errormsg,
4530 sizeof(errormsg),
4531 EXEC_ASYNC,
4532 args,
4533 NULL,
4534 &rcodes,
4535 shell);
4536 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004537}
4538
Guido van Rossumd48f2521997-12-05 22:19:34 +00004539static FILE *
4540popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004541{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004542 int oldfd, tgtfd;
4543 HFILE pipeh[2];
4544 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004545
Victor Stinnerd6f85422010-05-05 23:33:33 +00004546 /* mode determines which of stdin or stdout is reconnected to
4547 * the pipe to the child
4548 */
4549 if (strchr(mode, 'r') != NULL) {
4550 tgt_fd = 1; /* stdout */
4551 } else if (strchr(mode, 'w')) {
4552 tgt_fd = 0; /* stdin */
4553 } else {
4554 *err = ERROR_INVALID_ACCESS;
4555 return NULL;
4556 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004557
Victor Stinnerd6f85422010-05-05 23:33:33 +00004558 /* setup the pipe */
4559 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4560 *err = rc;
4561 return NULL;
4562 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004563
Victor Stinnerd6f85422010-05-05 23:33:33 +00004564 /* prevent other threads accessing stdio */
4565 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004566
Victor Stinnerd6f85422010-05-05 23:33:33 +00004567 /* reconnect stdio and execute child */
4568 oldfd = dup(tgtfd);
4569 close(tgtfd);
4570 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4571 DosClose(pipeh[tgtfd]);
4572 rc = async_system(command);
4573 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004574
Victor Stinnerd6f85422010-05-05 23:33:33 +00004575 /* restore stdio */
4576 dup2(oldfd, tgtfd);
4577 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004578
Victor Stinnerd6f85422010-05-05 23:33:33 +00004579 /* allow other threads access to stdio */
4580 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004581
Victor Stinnerd6f85422010-05-05 23:33:33 +00004582 /* if execution of child was successful return file stream */
4583 if (rc == NO_ERROR)
4584 return fdopen(pipeh[1 - tgtfd], mode);
4585 else {
4586 DosClose(pipeh[1 - tgtfd]);
4587 *err = rc;
4588 return NULL;
4589 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004590}
4591
4592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004593posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004594{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004595 char *name;
4596 char *mode = "r";
4597 int err, bufsize = -1;
4598 FILE *fp;
4599 PyObject *f;
4600 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4601 return NULL;
4602 Py_BEGIN_ALLOW_THREADS
4603 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4604 Py_END_ALLOW_THREADS
4605 if (fp == NULL)
4606 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004607
Victor Stinnerd6f85422010-05-05 23:33:33 +00004608 f = PyFile_FromFile(fp, name, mode, fclose);
4609 if (f != NULL)
4610 PyFile_SetBufSize(f, bufsize);
4611 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004612}
4613
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004614#elif defined(PYCC_GCC)
4615
4616/* standard posix version of popen() support */
4617static PyObject *
4618posix_popen(PyObject *self, PyObject *args)
4619{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004620 char *name;
4621 char *mode = "r";
4622 int bufsize = -1;
4623 FILE *fp;
4624 PyObject *f;
4625 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4626 return NULL;
4627 Py_BEGIN_ALLOW_THREADS
4628 fp = popen(name, mode);
4629 Py_END_ALLOW_THREADS
4630 if (fp == NULL)
4631 return posix_error();
4632 f = PyFile_FromFile(fp, name, mode, pclose);
4633 if (f != NULL)
4634 PyFile_SetBufSize(f, bufsize);
4635 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004636}
4637
4638/* fork() under OS/2 has lots'o'warts
4639 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4640 * most of this code is a ripoff of the win32 code, but using the
4641 * capabilities of EMX's C library routines
4642 */
4643
4644/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4645#define POPEN_1 1
4646#define POPEN_2 2
4647#define POPEN_3 3
4648#define POPEN_4 4
4649
4650static PyObject *_PyPopen(char *, int, int, int);
4651static int _PyPclose(FILE *file);
4652
4653/*
4654 * Internal dictionary mapping popen* file pointers to process handles,
4655 * for use when retrieving the process exit code. See _PyPclose() below
4656 * for more information on this dictionary's use.
4657 */
4658static PyObject *_PyPopenProcs = NULL;
4659
4660/* os2emx version of popen2()
4661 *
4662 * The result of this function is a pipe (file) connected to the
4663 * process's stdin, and a pipe connected to the process's stdout.
4664 */
4665
4666static PyObject *
4667os2emx_popen2(PyObject *self, PyObject *args)
4668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004669 PyObject *f;
4670 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004671
Victor Stinnerd6f85422010-05-05 23:33:33 +00004672 char *cmdstring;
4673 char *mode = "t";
4674 int bufsize = -1;
4675 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4676 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004677
Victor Stinnerd6f85422010-05-05 23:33:33 +00004678 if (*mode == 't')
4679 tm = O_TEXT;
4680 else if (*mode != 'b') {
4681 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4682 return NULL;
4683 } else
4684 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004685
Victor Stinnerd6f85422010-05-05 23:33:33 +00004686 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004687
Victor Stinnerd6f85422010-05-05 23:33:33 +00004688 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004689}
4690
4691/*
4692 * Variation on os2emx.popen2
4693 *
4694 * The result of this function is 3 pipes - the process's stdin,
4695 * stdout and stderr
4696 */
4697
4698static PyObject *
4699os2emx_popen3(PyObject *self, PyObject *args)
4700{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004701 PyObject *f;
4702 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004703
Victor Stinnerd6f85422010-05-05 23:33:33 +00004704 char *cmdstring;
4705 char *mode = "t";
4706 int bufsize = -1;
4707 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4708 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004709
Victor Stinnerd6f85422010-05-05 23:33:33 +00004710 if (*mode == 't')
4711 tm = O_TEXT;
4712 else if (*mode != 'b') {
4713 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4714 return NULL;
4715 } else
4716 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004717
Victor Stinnerd6f85422010-05-05 23:33:33 +00004718 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004719
Victor Stinnerd6f85422010-05-05 23:33:33 +00004720 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004721}
4722
4723/*
4724 * Variation on os2emx.popen2
4725 *
Tim Peters11b23062003-04-23 02:39:17 +00004726 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004727 * and stdout+stderr combined as a single pipe.
4728 */
4729
4730static PyObject *
4731os2emx_popen4(PyObject *self, PyObject *args)
4732{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004733 PyObject *f;
4734 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004735
Victor Stinnerd6f85422010-05-05 23:33:33 +00004736 char *cmdstring;
4737 char *mode = "t";
4738 int bufsize = -1;
4739 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4740 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004741
Victor Stinnerd6f85422010-05-05 23:33:33 +00004742 if (*mode == 't')
4743 tm = O_TEXT;
4744 else if (*mode != 'b') {
4745 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4746 return NULL;
4747 } else
4748 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004749
Victor Stinnerd6f85422010-05-05 23:33:33 +00004750 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004751
Victor Stinnerd6f85422010-05-05 23:33:33 +00004752 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004753}
4754
4755/* a couple of structures for convenient handling of multiple
4756 * file handles and pipes
4757 */
4758struct file_ref
4759{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004760 int handle;
4761 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004762};
4763
4764struct pipe_ref
4765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004766 int rd;
4767 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004768};
4769
4770/* The following code is derived from the win32 code */
4771
4772static PyObject *
4773_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4774{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004775 struct file_ref stdio[3];
4776 struct pipe_ref p_fd[3];
4777 FILE *p_s[3];
4778 int file_count, i, pipe_err;
4779 pid_t pipe_pid;
4780 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4781 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004782
Victor Stinnerd6f85422010-05-05 23:33:33 +00004783 /* file modes for subsequent fdopen's on pipe handles */
4784 if (mode == O_TEXT)
4785 {
4786 rd_mode = "rt";
4787 wr_mode = "wt";
4788 }
4789 else
4790 {
4791 rd_mode = "rb";
4792 wr_mode = "wb";
4793 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004794
Victor Stinnerd6f85422010-05-05 23:33:33 +00004795 /* prepare shell references */
4796 if ((shell = getenv("EMXSHELL")) == NULL)
4797 if ((shell = getenv("COMSPEC")) == NULL)
4798 {
4799 errno = ENOENT;
4800 return posix_error();
4801 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004802
Victor Stinnerd6f85422010-05-05 23:33:33 +00004803 sh_name = _getname(shell);
4804 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4805 opt = "/c";
4806 else
4807 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004808
Victor Stinnerd6f85422010-05-05 23:33:33 +00004809 /* save current stdio fds + their flags, and set not inheritable */
4810 i = pipe_err = 0;
4811 while (pipe_err >= 0 && i < 3)
4812 {
4813 pipe_err = stdio[i].handle = dup(i);
4814 stdio[i].flags = fcntl(i, F_GETFD, 0);
4815 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4816 i++;
4817 }
4818 if (pipe_err < 0)
4819 {
4820 /* didn't get them all saved - clean up and bail out */
4821 int saved_err = errno;
4822 while (i-- > 0)
4823 {
4824 close(stdio[i].handle);
4825 }
4826 errno = saved_err;
4827 return posix_error();
4828 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004829
Victor Stinnerd6f85422010-05-05 23:33:33 +00004830 /* create pipe ends */
4831 file_count = 2;
4832 if (n == POPEN_3)
4833 file_count = 3;
4834 i = pipe_err = 0;
4835 while ((pipe_err == 0) && (i < file_count))
4836 pipe_err = pipe((int *)&p_fd[i++]);
4837 if (pipe_err < 0)
4838 {
4839 /* didn't get them all made - clean up and bail out */
4840 while (i-- > 0)
4841 {
4842 close(p_fd[i].wr);
4843 close(p_fd[i].rd);
4844 }
4845 errno = EPIPE;
4846 return posix_error();
4847 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004848
Victor Stinnerd6f85422010-05-05 23:33:33 +00004849 /* change the actual standard IO streams over temporarily,
4850 * making the retained pipe ends non-inheritable
4851 */
4852 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004853
Victor Stinnerd6f85422010-05-05 23:33:33 +00004854 /* - stdin */
4855 if (dup2(p_fd[0].rd, 0) == 0)
4856 {
4857 close(p_fd[0].rd);
4858 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4859 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4860 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4861 {
4862 close(p_fd[0].wr);
4863 pipe_err = -1;
4864 }
4865 }
4866 else
4867 {
4868 pipe_err = -1;
4869 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004870
Victor Stinnerd6f85422010-05-05 23:33:33 +00004871 /* - stdout */
4872 if (pipe_err == 0)
4873 {
4874 if (dup2(p_fd[1].wr, 1) == 1)
4875 {
4876 close(p_fd[1].wr);
4877 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4878 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4879 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4880 {
4881 close(p_fd[1].rd);
4882 pipe_err = -1;
4883 }
4884 }
4885 else
4886 {
4887 pipe_err = -1;
4888 }
4889 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004890
Victor Stinnerd6f85422010-05-05 23:33:33 +00004891 /* - stderr, as required */
4892 if (pipe_err == 0)
4893 switch (n)
4894 {
4895 case POPEN_3:
4896 {
4897 if (dup2(p_fd[2].wr, 2) == 2)
4898 {
4899 close(p_fd[2].wr);
4900 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4901 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4902 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4903 {
4904 close(p_fd[2].rd);
4905 pipe_err = -1;
4906 }
4907 }
4908 else
4909 {
4910 pipe_err = -1;
4911 }
4912 break;
4913 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004914
Victor Stinnerd6f85422010-05-05 23:33:33 +00004915 case POPEN_4:
4916 {
4917 if (dup2(1, 2) != 2)
4918 {
4919 pipe_err = -1;
4920 }
4921 break;
4922 }
4923 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004924
Victor Stinnerd6f85422010-05-05 23:33:33 +00004925 /* spawn the child process */
4926 if (pipe_err == 0)
4927 {
4928 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4929 if (pipe_pid == -1)
4930 {
4931 pipe_err = -1;
4932 }
4933 else
4934 {
4935 /* save the PID into the FILE structure
4936 * NOTE: this implementation doesn't actually
4937 * take advantage of this, but do it for
4938 * completeness - AIM Apr01
4939 */
4940 for (i = 0; i < file_count; i++)
4941 p_s[i]->_pid = pipe_pid;
4942 }
4943 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004944
Victor Stinnerd6f85422010-05-05 23:33:33 +00004945 /* reset standard IO to normal */
4946 for (i = 0; i < 3; i++)
4947 {
4948 dup2(stdio[i].handle, i);
4949 fcntl(i, F_SETFD, stdio[i].flags);
4950 close(stdio[i].handle);
4951 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004952
Victor Stinnerd6f85422010-05-05 23:33:33 +00004953 /* if any remnant problems, clean up and bail out */
4954 if (pipe_err < 0)
4955 {
4956 for (i = 0; i < 3; i++)
4957 {
4958 close(p_fd[i].rd);
4959 close(p_fd[i].wr);
4960 }
4961 errno = EPIPE;
4962 return posix_error_with_filename(cmdstring);
4963 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004964
Victor Stinnerd6f85422010-05-05 23:33:33 +00004965 /* build tuple of file objects to return */
4966 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4967 PyFile_SetBufSize(p_f[0], bufsize);
4968 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4969 PyFile_SetBufSize(p_f[1], bufsize);
4970 if (n == POPEN_3)
4971 {
4972 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4973 PyFile_SetBufSize(p_f[0], bufsize);
4974 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4975 }
4976 else
4977 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004978
Victor Stinnerd6f85422010-05-05 23:33:33 +00004979 /*
4980 * Insert the files we've created into the process dictionary
4981 * all referencing the list with the process handle and the
4982 * initial number of files (see description below in _PyPclose).
4983 * Since if _PyPclose later tried to wait on a process when all
4984 * handles weren't closed, it could create a deadlock with the
4985 * child, we spend some energy here to try to ensure that we
4986 * either insert all file handles into the dictionary or none
4987 * at all. It's a little clumsy with the various popen modes
4988 * and variable number of files involved.
4989 */
4990 if (!_PyPopenProcs)
4991 {
4992 _PyPopenProcs = PyDict_New();
4993 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004994
Victor Stinnerd6f85422010-05-05 23:33:33 +00004995 if (_PyPopenProcs)
4996 {
4997 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4998 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004999
Victor Stinnerd6f85422010-05-05 23:33:33 +00005000 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5001 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005002
Victor Stinnerd6f85422010-05-05 23:33:33 +00005003 procObj = PyList_New(2);
5004 pidObj = PyLong_FromPid(pipe_pid);
5005 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005006
Victor Stinnerd6f85422010-05-05 23:33:33 +00005007 if (procObj && pidObj && intObj)
5008 {
5009 PyList_SetItem(procObj, 0, pidObj);
5010 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005011
Victor Stinnerd6f85422010-05-05 23:33:33 +00005012 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
5013 if (fileObj[0])
5014 {
5015 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5016 fileObj[0],
5017 procObj);
5018 }
5019 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5020 if (fileObj[1])
5021 {
5022 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5023 fileObj[1],
5024 procObj);
5025 }
5026 if (file_count >= 3)
5027 {
5028 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5029 if (fileObj[2])
5030 {
5031 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5032 fileObj[2],
5033 procObj);
5034 }
5035 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005036
Victor Stinnerd6f85422010-05-05 23:33:33 +00005037 if (ins_rc[0] < 0 || !fileObj[0] ||
5038 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5039 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5040 {
5041 /* Something failed - remove any dictionary
5042 * entries that did make it.
5043 */
5044 if (!ins_rc[0] && fileObj[0])
5045 {
5046 PyDict_DelItem(_PyPopenProcs,
5047 fileObj[0]);
5048 }
5049 if (!ins_rc[1] && fileObj[1])
5050 {
5051 PyDict_DelItem(_PyPopenProcs,
5052 fileObj[1]);
5053 }
5054 if (!ins_rc[2] && fileObj[2])
5055 {
5056 PyDict_DelItem(_PyPopenProcs,
5057 fileObj[2]);
5058 }
5059 }
5060 }
Tim Peters11b23062003-04-23 02:39:17 +00005061
Victor Stinnerd6f85422010-05-05 23:33:33 +00005062 /*
5063 * Clean up our localized references for the dictionary keys
5064 * and value since PyDict_SetItem will Py_INCREF any copies
5065 * that got placed in the dictionary.
5066 */
5067 Py_XDECREF(procObj);
5068 Py_XDECREF(fileObj[0]);
5069 Py_XDECREF(fileObj[1]);
5070 Py_XDECREF(fileObj[2]);
5071 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005072
Victor Stinnerd6f85422010-05-05 23:33:33 +00005073 /* Child is launched. */
5074 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005075}
5076
5077/*
5078 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5079 * exit code for the child process and return as a result of the close.
5080 *
5081 * This function uses the _PyPopenProcs dictionary in order to map the
5082 * input file pointer to information about the process that was
5083 * originally created by the popen* call that created the file pointer.
5084 * The dictionary uses the file pointer as a key (with one entry
5085 * inserted for each file returned by the original popen* call) and a
5086 * single list object as the value for all files from a single call.
5087 * The list object contains the Win32 process handle at [0], and a file
5088 * count at [1], which is initialized to the total number of file
5089 * handles using that list.
5090 *
5091 * This function closes whichever handle it is passed, and decrements
5092 * the file count in the dictionary for the process handle pointed to
5093 * by this file. On the last close (when the file count reaches zero),
5094 * this function will wait for the child process and then return its
5095 * exit code as the result of the close() operation. This permits the
5096 * files to be closed in any order - it is always the close() of the
5097 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005098 *
5099 * NOTE: This function is currently called with the GIL released.
5100 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005101 */
5102
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005103static int _PyPclose(FILE *file)
5104{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005105 int result;
5106 int exit_code;
5107 pid_t pipe_pid;
5108 PyObject *procObj, *pidObj, *intObj, *fileObj;
5109 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005110#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005111 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005112#endif
5113
Victor Stinnerd6f85422010-05-05 23:33:33 +00005114 /* Close the file handle first, to ensure it can't block the
5115 * child from exiting if it's the last handle.
5116 */
5117 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005118
5119#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005120 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005121#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005122 if (_PyPopenProcs)
5123 {
5124 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5125 (procObj = PyDict_GetItem(_PyPopenProcs,
5126 fileObj)) != NULL &&
5127 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5128 (intObj = PyList_GetItem(procObj,1)) != NULL)
5129 {
5130 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5131 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005132
Victor Stinnerd6f85422010-05-05 23:33:33 +00005133 if (file_count > 1)
5134 {
5135 /* Still other files referencing process */
5136 file_count--;
5137 PyList_SetItem(procObj,1,
5138 PyInt_FromLong((long) file_count));
5139 }
5140 else
5141 {
5142 /* Last file for this process */
5143 if (result != EOF &&
5144 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5145 {
5146 /* extract exit status */
5147 if (WIFEXITED(exit_code))
5148 {
5149 result = WEXITSTATUS(exit_code);
5150 }
5151 else
5152 {
5153 errno = EPIPE;
5154 result = -1;
5155 }
5156 }
5157 else
5158 {
5159 /* Indicate failure - this will cause the file object
5160 * to raise an I/O error and translate the last
5161 * error code from errno. We do have a problem with
5162 * last errors that overlap the normal errno table,
5163 * but that's a consistent problem with the file object.
5164 */
5165 result = -1;
5166 }
5167 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005168
Victor Stinnerd6f85422010-05-05 23:33:33 +00005169 /* Remove this file pointer from dictionary */
5170 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005171
Victor Stinnerd6f85422010-05-05 23:33:33 +00005172 if (PyDict_Size(_PyPopenProcs) == 0)
5173 {
5174 Py_DECREF(_PyPopenProcs);
5175 _PyPopenProcs = NULL;
5176 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005177
Victor Stinnerd6f85422010-05-05 23:33:33 +00005178 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005179
Victor Stinnerd6f85422010-05-05 23:33:33 +00005180 Py_XDECREF(fileObj);
5181 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005182
5183#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005184 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005185#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005186 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005187}
5188
5189#endif /* PYCC_??? */
5190
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005191#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005192
5193/*
5194 * Portable 'popen' replacement for Win32.
5195 *
5196 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5197 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005198 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005199 */
5200
5201#include <malloc.h>
5202#include <io.h>
5203#include <fcntl.h>
5204
5205/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5206#define POPEN_1 1
5207#define POPEN_2 2
5208#define POPEN_3 3
5209#define POPEN_4 4
5210
5211static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005212static int _PyPclose(FILE *file);
5213
5214/*
5215 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005216 * for use when retrieving the process exit code. See _PyPclose() below
5217 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005218 */
5219static PyObject *_PyPopenProcs = NULL;
5220
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005221
5222/* popen that works from a GUI.
5223 *
5224 * The result of this function is a pipe (file) connected to the
5225 * processes stdin or stdout, depending on the requested mode.
5226 */
5227
5228static PyObject *
5229posix_popen(PyObject *self, PyObject *args)
5230{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005231 PyObject *f;
5232 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005233
Victor Stinnerd6f85422010-05-05 23:33:33 +00005234 char *cmdstring;
5235 char *mode = "r";
5236 int bufsize = -1;
5237 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5238 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005239
Victor Stinnerd6f85422010-05-05 23:33:33 +00005240 if (*mode == 'r')
5241 tm = _O_RDONLY;
5242 else if (*mode != 'w') {
5243 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5244 return NULL;
5245 } else
5246 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005247
Victor Stinnerd6f85422010-05-05 23:33:33 +00005248 if (bufsize != -1) {
5249 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5250 return NULL;
5251 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005252
Victor Stinnerd6f85422010-05-05 23:33:33 +00005253 if (*(mode+1) == 't')
5254 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5255 else if (*(mode+1) == 'b')
5256 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5257 else
5258 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005259
Victor Stinnerd6f85422010-05-05 23:33:33 +00005260 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005261}
5262
5263/* Variation on win32pipe.popen
5264 *
5265 * The result of this function is a pipe (file) connected to the
5266 * process's stdin, and a pipe connected to the process's stdout.
5267 */
5268
5269static PyObject *
5270win32_popen2(PyObject *self, PyObject *args)
5271{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005272 PyObject *f;
5273 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005274
Victor Stinnerd6f85422010-05-05 23:33:33 +00005275 char *cmdstring;
5276 char *mode = "t";
5277 int bufsize = -1;
5278 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5279 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005280
Victor Stinnerd6f85422010-05-05 23:33:33 +00005281 if (*mode == 't')
5282 tm = _O_TEXT;
5283 else if (*mode != 'b') {
5284 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5285 return NULL;
5286 } else
5287 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005288
Victor Stinnerd6f85422010-05-05 23:33:33 +00005289 if (bufsize != -1) {
5290 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5291 return NULL;
5292 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005293
Victor Stinnerd6f85422010-05-05 23:33:33 +00005294 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005295
Victor Stinnerd6f85422010-05-05 23:33:33 +00005296 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005297}
5298
5299/*
5300 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005301 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005302 * The result of this function is 3 pipes - the process's stdin,
5303 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005304 */
5305
5306static PyObject *
5307win32_popen3(PyObject *self, PyObject *args)
5308{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005309 PyObject *f;
5310 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005311
Victor Stinnerd6f85422010-05-05 23:33:33 +00005312 char *cmdstring;
5313 char *mode = "t";
5314 int bufsize = -1;
5315 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5316 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005317
Victor Stinnerd6f85422010-05-05 23:33:33 +00005318 if (*mode == 't')
5319 tm = _O_TEXT;
5320 else if (*mode != 'b') {
5321 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5322 return NULL;
5323 } else
5324 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005325
Victor Stinnerd6f85422010-05-05 23:33:33 +00005326 if (bufsize != -1) {
5327 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5328 return NULL;
5329 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005330
Victor Stinnerd6f85422010-05-05 23:33:33 +00005331 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005332
Victor Stinnerd6f85422010-05-05 23:33:33 +00005333 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005334}
5335
5336/*
5337 * Variation on win32pipe.popen
5338 *
Tim Peters5aa91602002-01-30 05:46:57 +00005339 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005340 * and stdout+stderr combined as a single pipe.
5341 */
5342
5343static PyObject *
5344win32_popen4(PyObject *self, PyObject *args)
5345{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005346 PyObject *f;
5347 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005348
Victor Stinnerd6f85422010-05-05 23:33:33 +00005349 char *cmdstring;
5350 char *mode = "t";
5351 int bufsize = -1;
5352 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5353 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005354
Victor Stinnerd6f85422010-05-05 23:33:33 +00005355 if (*mode == 't')
5356 tm = _O_TEXT;
5357 else if (*mode != 'b') {
5358 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5359 return NULL;
5360 } else
5361 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005362
Victor Stinnerd6f85422010-05-05 23:33:33 +00005363 if (bufsize != -1) {
5364 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5365 return NULL;
5366 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005367
Victor Stinnerd6f85422010-05-05 23:33:33 +00005368 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005369
Victor Stinnerd6f85422010-05-05 23:33:33 +00005370 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005371}
5372
Mark Hammond08501372001-01-31 07:30:29 +00005373static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005374_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005375 HANDLE hStdin,
5376 HANDLE hStdout,
5377 HANDLE hStderr,
5378 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005379{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005380 PROCESS_INFORMATION piProcInfo;
5381 STARTUPINFO siStartInfo;
5382 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5383 char *s1,*s2, *s3 = " /c ";
5384 const char *szConsoleSpawn = "w9xpopen.exe";
5385 int i;
5386 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005387
Victor Stinnerd6f85422010-05-05 23:33:33 +00005388 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5389 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005390
Victor Stinnerd6f85422010-05-05 23:33:33 +00005391 s1 = (char *)alloca(i);
5392 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5393 /* x < i, so x fits into an integer */
5394 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005395
Victor Stinnerd6f85422010-05-05 23:33:33 +00005396 /* Explicitly check if we are using COMMAND.COM. If we are
5397 * then use the w9xpopen hack.
5398 */
5399 comshell = s1 + x;
5400 while (comshell >= s1 && *comshell != '\\')
5401 --comshell;
5402 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005403
Victor Stinnerd6f85422010-05-05 23:33:33 +00005404 if (GetVersion() < 0x80000000 &&
5405 _stricmp(comshell, "command.com") != 0) {
5406 /* NT/2000 and not using command.com. */
5407 x = i + strlen(s3) + strlen(cmdstring) + 1;
5408 s2 = (char *)alloca(x);
5409 ZeroMemory(s2, x);
5410 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5411 }
5412 else {
5413 /*
5414 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5415 * the workaround listed in KB: Q150956
5416 */
5417 char modulepath[_MAX_PATH];
5418 struct stat statinfo;
5419 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5420 for (x = i = 0; modulepath[i]; i++)
5421 if (modulepath[i] == SEP)
5422 x = i+1;
5423 modulepath[x] = '\0';
5424 /* Create the full-name to w9xpopen, so we can test it exists */
5425 strncat(modulepath,
5426 szConsoleSpawn,
5427 (sizeof(modulepath)/sizeof(modulepath[0]))
5428 -strlen(modulepath));
5429 if (stat(modulepath, &statinfo) != 0) {
5430 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5431 /* Eeek - file-not-found - possibly an embedding
5432 situation - see if we can locate it in sys.prefix
5433 */
5434 strncpy(modulepath,
5435 Py_GetExecPrefix(),
5436 mplen);
5437 modulepath[mplen-1] = '\0';
5438 if (modulepath[strlen(modulepath)-1] != '\\')
5439 strcat(modulepath, "\\");
5440 strncat(modulepath,
5441 szConsoleSpawn,
5442 mplen-strlen(modulepath));
5443 /* No where else to look - raise an easily identifiable
5444 error, rather than leaving Windows to report
5445 "file not found" - as the user is probably blissfully
5446 unaware this shim EXE is used, and it will confuse them.
5447 (well, it confused me for a while ;-)
5448 */
5449 if (stat(modulepath, &statinfo) != 0) {
5450 PyErr_Format(PyExc_RuntimeError,
5451 "Can not locate '%s' which is needed "
5452 "for popen to work with your shell "
5453 "or platform.",
5454 szConsoleSpawn);
5455 return FALSE;
5456 }
5457 }
5458 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5459 strlen(modulepath) +
5460 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005461
Victor Stinnerd6f85422010-05-05 23:33:33 +00005462 s2 = (char *)alloca(x);
5463 ZeroMemory(s2, x);
5464 /* To maintain correct argument passing semantics,
5465 we pass the command-line as it stands, and allow
5466 quoting to be applied. w9xpopen.exe will then
5467 use its argv vector, and re-quote the necessary
5468 args for the ultimate child process.
5469 */
5470 PyOS_snprintf(
5471 s2, x,
5472 "\"%s\" %s%s%s",
5473 modulepath,
5474 s1,
5475 s3,
5476 cmdstring);
5477 /* Not passing CREATE_NEW_CONSOLE has been known to
5478 cause random failures on win9x. Specifically a
5479 dialog:
5480 "Your program accessed mem currently in use at xxx"
5481 and a hopeful warning about the stability of your
5482 system.
5483 Cost is Ctrl+C won't kill children, but anyone
5484 who cares can have a go!
5485 */
5486 dwProcessFlags |= CREATE_NEW_CONSOLE;
5487 }
5488 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005489
Victor Stinnerd6f85422010-05-05 23:33:33 +00005490 /* Could be an else here to try cmd.exe / command.com in the path
5491 Now we'll just error out.. */
5492 else {
5493 PyErr_SetString(PyExc_RuntimeError,
5494 "Cannot locate a COMSPEC environment variable to "
5495 "use as the shell");
5496 return FALSE;
5497 }
Tim Peters5aa91602002-01-30 05:46:57 +00005498
Victor Stinnerd6f85422010-05-05 23:33:33 +00005499 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5500 siStartInfo.cb = sizeof(STARTUPINFO);
5501 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5502 siStartInfo.hStdInput = hStdin;
5503 siStartInfo.hStdOutput = hStdout;
5504 siStartInfo.hStdError = hStderr;
5505 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005506
Victor Stinnerd6f85422010-05-05 23:33:33 +00005507 if (CreateProcess(NULL,
5508 s2,
5509 NULL,
5510 NULL,
5511 TRUE,
5512 dwProcessFlags,
5513 NULL,
5514 NULL,
5515 &siStartInfo,
5516 &piProcInfo) ) {
5517 /* Close the handles now so anyone waiting is woken. */
5518 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005519
Victor Stinnerd6f85422010-05-05 23:33:33 +00005520 /* Return process handle */
5521 *hProcess = piProcInfo.hProcess;
5522 return TRUE;
5523 }
5524 win32_error("CreateProcess", s2);
5525 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005526}
5527
5528/* The following code is based off of KB: Q190351 */
5529
5530static PyObject *
5531_PyPopen(char *cmdstring, int mode, int n)
5532{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005533 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5534 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5535 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005536
Victor Stinnerd6f85422010-05-05 23:33:33 +00005537 SECURITY_ATTRIBUTES saAttr;
5538 BOOL fSuccess;
5539 int fd1, fd2, fd3;
5540 FILE *f1, *f2, *f3;
5541 long file_count;
5542 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005543
Victor Stinnerd6f85422010-05-05 23:33:33 +00005544 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5545 saAttr.bInheritHandle = TRUE;
5546 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005547
Victor Stinnerd6f85422010-05-05 23:33:33 +00005548 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5549 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005550
Victor Stinnerd6f85422010-05-05 23:33:33 +00005551 /* Create new output read handle and the input write handle. Set
5552 * the inheritance properties to FALSE. Otherwise, the child inherits
5553 * these handles; resulting in non-closeable handles to the pipes
5554 * being created. */
5555 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5556 GetCurrentProcess(), &hChildStdinWrDup, 0,
5557 FALSE,
5558 DUPLICATE_SAME_ACCESS);
5559 if (!fSuccess)
5560 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005561
Victor Stinnerd6f85422010-05-05 23:33:33 +00005562 /* Close the inheritable version of ChildStdin
5563 that we're using. */
5564 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005565
Victor Stinnerd6f85422010-05-05 23:33:33 +00005566 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5567 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005568
Victor Stinnerd6f85422010-05-05 23:33:33 +00005569 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5570 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5571 FALSE, DUPLICATE_SAME_ACCESS);
5572 if (!fSuccess)
5573 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005574
Victor Stinnerd6f85422010-05-05 23:33:33 +00005575 /* Close the inheritable version of ChildStdout
5576 that we're using. */
5577 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005578
Victor Stinnerd6f85422010-05-05 23:33:33 +00005579 if (n != POPEN_4) {
5580 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5581 return win32_error("CreatePipe", NULL);
5582 fSuccess = DuplicateHandle(GetCurrentProcess(),
5583 hChildStderrRd,
5584 GetCurrentProcess(),
5585 &hChildStderrRdDup, 0,
5586 FALSE, DUPLICATE_SAME_ACCESS);
5587 if (!fSuccess)
5588 return win32_error("DuplicateHandle", NULL);
5589 /* Close the inheritable version of ChildStdErr that we're using. */
5590 CloseHandle(hChildStderrRd);
5591 }
Tim Peters5aa91602002-01-30 05:46:57 +00005592
Victor Stinnerd6f85422010-05-05 23:33:33 +00005593 switch (n) {
5594 case POPEN_1:
5595 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5596 case _O_WRONLY | _O_TEXT:
5597 /* Case for writing to child Stdin in text mode. */
5598 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5599 f1 = _fdopen(fd1, "w");
5600 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5601 PyFile_SetBufSize(f, 0);
5602 /* We don't care about these pipes anymore, so close them. */
5603 CloseHandle(hChildStdoutRdDup);
5604 CloseHandle(hChildStderrRdDup);
5605 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005606
Victor Stinnerd6f85422010-05-05 23:33:33 +00005607 case _O_RDONLY | _O_TEXT:
5608 /* Case for reading from child Stdout in text mode. */
5609 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5610 f1 = _fdopen(fd1, "r");
5611 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5612 PyFile_SetBufSize(f, 0);
5613 /* We don't care about these pipes anymore, so close them. */
5614 CloseHandle(hChildStdinWrDup);
5615 CloseHandle(hChildStderrRdDup);
5616 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005617
Victor Stinnerd6f85422010-05-05 23:33:33 +00005618 case _O_RDONLY | _O_BINARY:
5619 /* Case for readinig from child Stdout in binary mode. */
5620 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5621 f1 = _fdopen(fd1, "rb");
5622 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5623 PyFile_SetBufSize(f, 0);
5624 /* We don't care about these pipes anymore, so close them. */
5625 CloseHandle(hChildStdinWrDup);
5626 CloseHandle(hChildStderrRdDup);
5627 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005628
Victor Stinnerd6f85422010-05-05 23:33:33 +00005629 case _O_WRONLY | _O_BINARY:
5630 /* Case for writing to child Stdin in binary mode. */
5631 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5632 f1 = _fdopen(fd1, "wb");
5633 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5634 PyFile_SetBufSize(f, 0);
5635 /* We don't care about these pipes anymore, so close them. */
5636 CloseHandle(hChildStdoutRdDup);
5637 CloseHandle(hChildStderrRdDup);
5638 break;
5639 }
5640 file_count = 1;
5641 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005642
Victor Stinnerd6f85422010-05-05 23:33:33 +00005643 case POPEN_2:
5644 case POPEN_4:
5645 {
5646 char *m1, *m2;
5647 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005648
Victor Stinnerd6f85422010-05-05 23:33:33 +00005649 if (mode & _O_TEXT) {
5650 m1 = "r";
5651 m2 = "w";
5652 } else {
5653 m1 = "rb";
5654 m2 = "wb";
5655 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005656
Victor Stinnerd6f85422010-05-05 23:33:33 +00005657 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5658 f1 = _fdopen(fd1, m2);
5659 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5660 f2 = _fdopen(fd2, m1);
5661 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5662 PyFile_SetBufSize(p1, 0);
5663 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5664 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005665
Victor Stinnerd6f85422010-05-05 23:33:33 +00005666 if (n != 4)
5667 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005668
Victor Stinnerd6f85422010-05-05 23:33:33 +00005669 f = PyTuple_Pack(2,p1,p2);
5670 Py_XDECREF(p1);
5671 Py_XDECREF(p2);
5672 file_count = 2;
5673 break;
5674 }
Tim Peters5aa91602002-01-30 05:46:57 +00005675
Victor Stinnerd6f85422010-05-05 23:33:33 +00005676 case POPEN_3:
5677 {
5678 char *m1, *m2;
5679 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005680
Victor Stinnerd6f85422010-05-05 23:33:33 +00005681 if (mode & _O_TEXT) {
5682 m1 = "r";
5683 m2 = "w";
5684 } else {
5685 m1 = "rb";
5686 m2 = "wb";
5687 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005688
Victor Stinnerd6f85422010-05-05 23:33:33 +00005689 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5690 f1 = _fdopen(fd1, m2);
5691 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5692 f2 = _fdopen(fd2, m1);
5693 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5694 f3 = _fdopen(fd3, m1);
5695 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5696 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5697 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5698 PyFile_SetBufSize(p1, 0);
5699 PyFile_SetBufSize(p2, 0);
5700 PyFile_SetBufSize(p3, 0);
5701 f = PyTuple_Pack(3,p1,p2,p3);
5702 Py_XDECREF(p1);
5703 Py_XDECREF(p2);
5704 Py_XDECREF(p3);
5705 file_count = 3;
5706 break;
5707 }
5708 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005709
Victor Stinnerd6f85422010-05-05 23:33:33 +00005710 if (n == POPEN_4) {
5711 if (!_PyPopenCreateProcess(cmdstring,
5712 hChildStdinRd,
5713 hChildStdoutWr,
5714 hChildStdoutWr,
5715 &hProcess))
5716 return NULL;
5717 }
5718 else {
5719 if (!_PyPopenCreateProcess(cmdstring,
5720 hChildStdinRd,
5721 hChildStdoutWr,
5722 hChildStderrWr,
5723 &hProcess))
5724 return NULL;
5725 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005726
Victor Stinnerd6f85422010-05-05 23:33:33 +00005727 /*
5728 * Insert the files we've created into the process dictionary
5729 * all referencing the list with the process handle and the
5730 * initial number of files (see description below in _PyPclose).
5731 * Since if _PyPclose later tried to wait on a process when all
5732 * handles weren't closed, it could create a deadlock with the
5733 * child, we spend some energy here to try to ensure that we
5734 * either insert all file handles into the dictionary or none
5735 * at all. It's a little clumsy with the various popen modes
5736 * and variable number of files involved.
5737 */
5738 if (!_PyPopenProcs) {
5739 _PyPopenProcs = PyDict_New();
5740 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005741
Victor Stinnerd6f85422010-05-05 23:33:33 +00005742 if (_PyPopenProcs) {
5743 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5744 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005745
Victor Stinnerd6f85422010-05-05 23:33:33 +00005746 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5747 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005748
Victor Stinnerd6f85422010-05-05 23:33:33 +00005749 procObj = PyList_New(2);
5750 hProcessObj = PyLong_FromVoidPtr(hProcess);
5751 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005752
Victor Stinnerd6f85422010-05-05 23:33:33 +00005753 if (procObj && hProcessObj && intObj) {
5754 PyList_SetItem(procObj,0,hProcessObj);
5755 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005756
Victor Stinnerd6f85422010-05-05 23:33:33 +00005757 fileObj[0] = PyLong_FromVoidPtr(f1);
5758 if (fileObj[0]) {
5759 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5760 fileObj[0],
5761 procObj);
5762 }
5763 if (file_count >= 2) {
5764 fileObj[1] = PyLong_FromVoidPtr(f2);
5765 if (fileObj[1]) {
5766 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5767 fileObj[1],
5768 procObj);
5769 }
5770 }
5771 if (file_count >= 3) {
5772 fileObj[2] = PyLong_FromVoidPtr(f3);
5773 if (fileObj[2]) {
5774 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5775 fileObj[2],
5776 procObj);
5777 }
5778 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005779
Victor Stinnerd6f85422010-05-05 23:33:33 +00005780 if (ins_rc[0] < 0 || !fileObj[0] ||
5781 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5782 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5783 /* Something failed - remove any dictionary
5784 * entries that did make it.
5785 */
5786 if (!ins_rc[0] && fileObj[0]) {
5787 PyDict_DelItem(_PyPopenProcs,
5788 fileObj[0]);
5789 }
5790 if (!ins_rc[1] && fileObj[1]) {
5791 PyDict_DelItem(_PyPopenProcs,
5792 fileObj[1]);
5793 }
5794 if (!ins_rc[2] && fileObj[2]) {
5795 PyDict_DelItem(_PyPopenProcs,
5796 fileObj[2]);
5797 }
5798 }
5799 }
Tim Peters5aa91602002-01-30 05:46:57 +00005800
Victor Stinnerd6f85422010-05-05 23:33:33 +00005801 /*
5802 * Clean up our localized references for the dictionary keys
5803 * and value since PyDict_SetItem will Py_INCREF any copies
5804 * that got placed in the dictionary.
5805 */
5806 Py_XDECREF(procObj);
5807 Py_XDECREF(fileObj[0]);
5808 Py_XDECREF(fileObj[1]);
5809 Py_XDECREF(fileObj[2]);
5810 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005811
Victor Stinnerd6f85422010-05-05 23:33:33 +00005812 /* Child is launched. Close the parents copy of those pipe
5813 * handles that only the child should have open. You need to
5814 * make sure that no handles to the write end of the output pipe
5815 * are maintained in this process or else the pipe will not close
5816 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005817
Victor Stinnerd6f85422010-05-05 23:33:33 +00005818 if (!CloseHandle(hChildStdinRd))
5819 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005820
Victor Stinnerd6f85422010-05-05 23:33:33 +00005821 if (!CloseHandle(hChildStdoutWr))
5822 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005823
Victor Stinnerd6f85422010-05-05 23:33:33 +00005824 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5825 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005826
Victor Stinnerd6f85422010-05-05 23:33:33 +00005827 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005828}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005829
5830/*
5831 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5832 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005833 *
5834 * This function uses the _PyPopenProcs dictionary in order to map the
5835 * input file pointer to information about the process that was
5836 * originally created by the popen* call that created the file pointer.
5837 * The dictionary uses the file pointer as a key (with one entry
5838 * inserted for each file returned by the original popen* call) and a
5839 * single list object as the value for all files from a single call.
5840 * The list object contains the Win32 process handle at [0], and a file
5841 * count at [1], which is initialized to the total number of file
5842 * handles using that list.
5843 *
5844 * This function closes whichever handle it is passed, and decrements
5845 * the file count in the dictionary for the process handle pointed to
5846 * by this file. On the last close (when the file count reaches zero),
5847 * this function will wait for the child process and then return its
5848 * exit code as the result of the close() operation. This permits the
5849 * files to be closed in any order - it is always the close() of the
5850 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005851 *
5852 * NOTE: This function is currently called with the GIL released.
5853 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005854 */
Tim Peters736aa322000-09-01 06:51:24 +00005855
Fredrik Lundh56055a42000-07-23 19:47:12 +00005856static int _PyPclose(FILE *file)
5857{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005858 int result;
5859 DWORD exit_code;
5860 HANDLE hProcess;
5861 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5862 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005863#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005864 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005865#endif
5866
Victor Stinnerd6f85422010-05-05 23:33:33 +00005867 /* Close the file handle first, to ensure it can't block the
5868 * child from exiting if it's the last handle.
5869 */
5870 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005871#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005872 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005873#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005874 if (_PyPopenProcs) {
5875 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5876 (procObj = PyDict_GetItem(_PyPopenProcs,
5877 fileObj)) != NULL &&
5878 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5879 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005880
Victor Stinnerd6f85422010-05-05 23:33:33 +00005881 hProcess = PyLong_AsVoidPtr(hProcessObj);
5882 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005883
Victor Stinnerd6f85422010-05-05 23:33:33 +00005884 if (file_count > 1) {
5885 /* Still other files referencing process */
5886 file_count--;
5887 PyList_SetItem(procObj,1,
5888 PyInt_FromLong(file_count));
5889 } else {
5890 /* Last file for this process */
5891 if (result != EOF &&
5892 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5893 GetExitCodeProcess(hProcess, &exit_code)) {
5894 /* Possible truncation here in 16-bit environments, but
5895 * real exit codes are just the lower byte in any event.
5896 */
5897 result = exit_code;
5898 } else {
5899 /* Indicate failure - this will cause the file object
5900 * to raise an I/O error and translate the last Win32
5901 * error code from errno. We do have a problem with
5902 * last errors that overlap the normal errno table,
5903 * but that's a consistent problem with the file object.
5904 */
5905 if (result != EOF) {
5906 /* If the error wasn't from the fclose(), then
5907 * set errno for the file object error handling.
5908 */
5909 errno = GetLastError();
5910 }
5911 result = -1;
5912 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005913
Victor Stinnerd6f85422010-05-05 23:33:33 +00005914 /* Free up the native handle at this point */
5915 CloseHandle(hProcess);
5916 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005917
Victor Stinnerd6f85422010-05-05 23:33:33 +00005918 /* Remove this file pointer from dictionary */
5919 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005920
Victor Stinnerd6f85422010-05-05 23:33:33 +00005921 if (PyDict_Size(_PyPopenProcs) == 0) {
5922 Py_DECREF(_PyPopenProcs);
5923 _PyPopenProcs = NULL;
5924 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005925
Victor Stinnerd6f85422010-05-05 23:33:33 +00005926 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005927
Victor Stinnerd6f85422010-05-05 23:33:33 +00005928 Py_XDECREF(fileObj);
5929 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005930
Tim Peters736aa322000-09-01 06:51:24 +00005931#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005932 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005933#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005934 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005935}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005936
5937#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005939posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005940{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005941 char *name;
5942 char *mode = "r";
5943 int bufsize = -1;
5944 FILE *fp;
5945 PyObject *f;
5946 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5947 return NULL;
5948 /* Strip mode of binary or text modifiers */
5949 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5950 mode = "r";
5951 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5952 mode = "w";
5953 Py_BEGIN_ALLOW_THREADS
5954 fp = popen(name, mode);
5955 Py_END_ALLOW_THREADS
5956 if (fp == NULL)
5957 return posix_error();
5958 f = PyFile_FromFile(fp, name, mode, pclose);
5959 if (f != NULL)
5960 PyFile_SetBufSize(f, bufsize);
5961 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005962}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005963
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005964#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005965#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005967
Guido van Rossumb6775db1994-08-01 11:34:53 +00005968#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005969PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005970"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971Set the current process's user id.");
5972
Barry Warsaw53699e91996-12-10 23:23:01 +00005973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005974posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005975{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005976 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005977 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005978 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005979 if (setuid(uid) < 0)
5980 return posix_error();
5981 Py_INCREF(Py_None);
5982 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005983}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005984#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005986
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005987#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005989"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005990Set the current process's effective user id.");
5991
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005992static PyObject *
5993posix_seteuid (PyObject *self, PyObject *args)
5994{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005995 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005996 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005997 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005998 if (seteuid(euid) < 0) {
5999 return posix_error();
6000 } else {
6001 Py_INCREF(Py_None);
6002 return Py_None;
6003 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006004}
6005#endif /* HAVE_SETEUID */
6006
6007#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006008PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006009"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006010Set the current process's effective group id.");
6011
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006012static PyObject *
6013posix_setegid (PyObject *self, PyObject *args)
6014{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006015 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006016 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006017 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006018 if (setegid(egid) < 0) {
6019 return posix_error();
6020 } else {
6021 Py_INCREF(Py_None);
6022 return Py_None;
6023 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006024}
6025#endif /* HAVE_SETEGID */
6026
6027#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006028PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006029"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006030Set the current process's real and effective user ids.");
6031
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006032static PyObject *
6033posix_setreuid (PyObject *self, PyObject *args)
6034{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006035 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006036 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6037 _Py_Uid_Converter, &ruid,
6038 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006039 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006040 if (setreuid(ruid, euid) < 0) {
6041 return posix_error();
6042 } else {
6043 Py_INCREF(Py_None);
6044 return Py_None;
6045 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006046}
6047#endif /* HAVE_SETREUID */
6048
6049#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006051"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052Set the current process's real and effective group ids.");
6053
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006054static PyObject *
6055posix_setregid (PyObject *self, PyObject *args)
6056{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006057 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006058 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6059 _Py_Gid_Converter, &rgid,
6060 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006061 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006062 if (setregid(rgid, egid) < 0) {
6063 return posix_error();
6064 } else {
6065 Py_INCREF(Py_None);
6066 return Py_None;
6067 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006068}
6069#endif /* HAVE_SETREGID */
6070
Guido van Rossumb6775db1994-08-01 11:34:53 +00006071#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006073"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006075
Barry Warsaw53699e91996-12-10 23:23:01 +00006076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006077posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006078{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006079 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006080 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006081 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006082 if (setgid(gid) < 0)
6083 return posix_error();
6084 Py_INCREF(Py_None);
6085 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006086}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006087#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006088
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006089#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006091"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006093
6094static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006095posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006096{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006097 int i, len;
6098 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006099
Victor Stinnerd6f85422010-05-05 23:33:33 +00006100 if (!PySequence_Check(groups)) {
6101 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6102 return NULL;
6103 }
6104 len = PySequence_Size(groups);
6105 if (len > MAX_GROUPS) {
6106 PyErr_SetString(PyExc_ValueError, "too many groups");
6107 return NULL;
6108 }
6109 for(i = 0; i < len; i++) {
6110 PyObject *elem;
6111 elem = PySequence_GetItem(groups, i);
6112 if (!elem)
6113 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006114 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6115 PyErr_SetString(PyExc_TypeError,
6116 "groups must be integers");
6117 Py_DECREF(elem);
6118 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006119 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006120 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006121 Py_DECREF(elem);
6122 return NULL;
6123 }
6124 }
6125 Py_DECREF(elem);
6126 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006127
Victor Stinnerd6f85422010-05-05 23:33:33 +00006128 if (setgroups(len, grouplist) < 0)
6129 return posix_error();
6130 Py_INCREF(Py_None);
6131 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006132}
6133#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006135#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006136static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006137wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006138{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006139 PyObject *result;
6140 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006141
Victor Stinnerd6f85422010-05-05 23:33:33 +00006142 if (pid == -1)
6143 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006144
Victor Stinnerd6f85422010-05-05 23:33:33 +00006145 if (struct_rusage == NULL) {
6146 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6147 if (m == NULL)
6148 return NULL;
6149 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6150 Py_DECREF(m);
6151 if (struct_rusage == NULL)
6152 return NULL;
6153 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006154
Victor Stinnerd6f85422010-05-05 23:33:33 +00006155 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6156 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6157 if (!result)
6158 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006159
6160#ifndef doubletime
6161#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6162#endif
6163
Victor Stinnerd6f85422010-05-05 23:33:33 +00006164 PyStructSequence_SET_ITEM(result, 0,
6165 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6166 PyStructSequence_SET_ITEM(result, 1,
6167 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006168#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006169 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6170 SET_INT(result, 2, ru->ru_maxrss);
6171 SET_INT(result, 3, ru->ru_ixrss);
6172 SET_INT(result, 4, ru->ru_idrss);
6173 SET_INT(result, 5, ru->ru_isrss);
6174 SET_INT(result, 6, ru->ru_minflt);
6175 SET_INT(result, 7, ru->ru_majflt);
6176 SET_INT(result, 8, ru->ru_nswap);
6177 SET_INT(result, 9, ru->ru_inblock);
6178 SET_INT(result, 10, ru->ru_oublock);
6179 SET_INT(result, 11, ru->ru_msgsnd);
6180 SET_INT(result, 12, ru->ru_msgrcv);
6181 SET_INT(result, 13, ru->ru_nsignals);
6182 SET_INT(result, 14, ru->ru_nvcsw);
6183 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006184#undef SET_INT
6185
Victor Stinnerd6f85422010-05-05 23:33:33 +00006186 if (PyErr_Occurred()) {
6187 Py_DECREF(result);
6188 return NULL;
6189 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006190
Victor Stinnerd6f85422010-05-05 23:33:33 +00006191 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006192}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006193#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006194
6195#ifdef HAVE_WAIT3
6196PyDoc_STRVAR(posix_wait3__doc__,
6197"wait3(options) -> (pid, status, rusage)\n\n\
6198Wait for completion of a child process.");
6199
6200static PyObject *
6201posix_wait3(PyObject *self, PyObject *args)
6202{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006203 pid_t pid;
6204 int options;
6205 struct rusage ru;
6206 WAIT_TYPE status;
6207 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006208
Victor Stinnerd6f85422010-05-05 23:33:33 +00006209 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6210 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006211
Victor Stinnerd6f85422010-05-05 23:33:33 +00006212 Py_BEGIN_ALLOW_THREADS
6213 pid = wait3(&status, options, &ru);
6214 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006215
Victor Stinnerd6f85422010-05-05 23:33:33 +00006216 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006217}
6218#endif /* HAVE_WAIT3 */
6219
6220#ifdef HAVE_WAIT4
6221PyDoc_STRVAR(posix_wait4__doc__,
6222"wait4(pid, options) -> (pid, status, rusage)\n\n\
6223Wait for completion of a given child process.");
6224
6225static PyObject *
6226posix_wait4(PyObject *self, PyObject *args)
6227{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006228 pid_t pid;
6229 int options;
6230 struct rusage ru;
6231 WAIT_TYPE status;
6232 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006233
Victor Stinnerd6f85422010-05-05 23:33:33 +00006234 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6235 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006236
Victor Stinnerd6f85422010-05-05 23:33:33 +00006237 Py_BEGIN_ALLOW_THREADS
6238 pid = wait4(pid, &status, options, &ru);
6239 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006240
Victor Stinnerd6f85422010-05-05 23:33:33 +00006241 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006242}
6243#endif /* HAVE_WAIT4 */
6244
Guido van Rossumb6775db1994-08-01 11:34:53 +00006245#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006246PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006247"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006248Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Barry Warsaw53699e91996-12-10 23:23:01 +00006250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006251posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006252{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006253 pid_t pid;
6254 int options;
6255 WAIT_TYPE status;
6256 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006257
Victor Stinnerd6f85422010-05-05 23:33:33 +00006258 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6259 return NULL;
6260 Py_BEGIN_ALLOW_THREADS
6261 pid = waitpid(pid, &status, options);
6262 Py_END_ALLOW_THREADS
6263 if (pid == -1)
6264 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006265
Victor Stinnerd6f85422010-05-05 23:33:33 +00006266 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006267}
6268
Tim Petersab034fa2002-02-01 11:27:43 +00006269#elif defined(HAVE_CWAIT)
6270
6271/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006272PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006273"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006274"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006275
6276static PyObject *
6277posix_waitpid(PyObject *self, PyObject *args)
6278{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006279 Py_intptr_t pid;
6280 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006281
Victor Stinnerd6f85422010-05-05 23:33:33 +00006282 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6283 return NULL;
6284 Py_BEGIN_ALLOW_THREADS
6285 pid = _cwait(&status, pid, options);
6286 Py_END_ALLOW_THREADS
6287 if (pid == -1)
6288 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006289
Victor Stinnerd6f85422010-05-05 23:33:33 +00006290 /* shift the status left a byte so this is more like the POSIX waitpid */
6291 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006292}
6293#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006294
Guido van Rossumad0ee831995-03-01 10:34:45 +00006295#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006296PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006297"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006299
Barry Warsaw53699e91996-12-10 23:23:01 +00006300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006301posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006302{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006303 pid_t pid;
6304 WAIT_TYPE status;
6305 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006306
Victor Stinnerd6f85422010-05-05 23:33:33 +00006307 Py_BEGIN_ALLOW_THREADS
6308 pid = wait(&status);
6309 Py_END_ALLOW_THREADS
6310 if (pid == -1)
6311 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006312
Victor Stinnerd6f85422010-05-05 23:33:33 +00006313 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006314}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006315#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006319"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006321
Barry Warsaw53699e91996-12-10 23:23:01 +00006322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006323posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006324{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006325#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006326 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006328#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006329 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006330#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006331 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006332#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006333#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006334}
6335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006336
Guido van Rossumb6775db1994-08-01 11:34:53 +00006337#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006338PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006339"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006340Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006341
Barry Warsaw53699e91996-12-10 23:23:01 +00006342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006343posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006344{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006345 PyObject* v;
6346 char buf[MAXPATHLEN];
6347 char *path;
6348 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006349#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006350 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006351#endif
6352
Victor Stinnerd6f85422010-05-05 23:33:33 +00006353 if (!PyArg_ParseTuple(args, "et:readlink",
6354 Py_FileSystemDefaultEncoding, &path))
6355 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006356#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006357 v = PySequence_GetItem(args, 0);
6358 if (v == NULL) {
6359 PyMem_Free(path);
6360 return NULL;
6361 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006362
Victor Stinnerd6f85422010-05-05 23:33:33 +00006363 if (PyUnicode_Check(v)) {
6364 arg_is_unicode = 1;
6365 }
6366 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006367#endif
6368
Victor Stinnerd6f85422010-05-05 23:33:33 +00006369 Py_BEGIN_ALLOW_THREADS
6370 n = readlink(path, buf, (int) sizeof buf);
6371 Py_END_ALLOW_THREADS
6372 if (n < 0)
6373 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006374
Victor Stinnerd6f85422010-05-05 23:33:33 +00006375 PyMem_Free(path);
6376 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006377#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006378 if (arg_is_unicode) {
6379 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006380
Victor Stinnerd6f85422010-05-05 23:33:33 +00006381 w = PyUnicode_FromEncodedObject(v,
6382 Py_FileSystemDefaultEncoding,
6383 "strict");
6384 if (w != NULL) {
6385 Py_DECREF(v);
6386 v = w;
6387 }
6388 else {
6389 /* fall back to the original byte string, as
6390 discussed in patch #683592 */
6391 PyErr_Clear();
6392 }
6393 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006394#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006395 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006397#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006399
Guido van Rossumb6775db1994-08-01 11:34:53 +00006400#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006401PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006402"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006403Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006404
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006406posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006407{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006408 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006409}
6410#endif /* HAVE_SYMLINK */
6411
6412
6413#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006414#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6415static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006416system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006417{
6418 ULONG value = 0;
6419
6420 Py_BEGIN_ALLOW_THREADS
6421 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6422 Py_END_ALLOW_THREADS
6423
6424 return value;
6425}
6426
6427static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006428posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006429{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006430 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006431 return Py_BuildValue("ddddd",
6432 (double)0 /* t.tms_utime / HZ */,
6433 (double)0 /* t.tms_stime / HZ */,
6434 (double)0 /* t.tms_cutime / HZ */,
6435 (double)0 /* t.tms_cstime / HZ */,
6436 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006437}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006438#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006439#define NEED_TICKS_PER_SECOND
6440static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006441static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006442posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006443{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006444 struct tms t;
6445 clock_t c;
6446 errno = 0;
6447 c = times(&t);
6448 if (c == (clock_t) -1)
6449 return posix_error();
6450 return Py_BuildValue("ddddd",
6451 (double)t.tms_utime / ticks_per_second,
6452 (double)t.tms_stime / ticks_per_second,
6453 (double)t.tms_cutime / ticks_per_second,
6454 (double)t.tms_cstime / ticks_per_second,
6455 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006456}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006457#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006458#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006459
6460
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006461#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006462#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006463static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006464posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006465{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006466 FILETIME create, exit, kernel, user;
6467 HANDLE hProc;
6468 hProc = GetCurrentProcess();
6469 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6470 /* The fields of a FILETIME structure are the hi and lo part
6471 of a 64-bit value expressed in 100 nanosecond units.
6472 1e7 is one second in such units; 1e-7 the inverse.
6473 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6474 */
6475 return Py_BuildValue(
6476 "ddddd",
6477 (double)(user.dwHighDateTime*429.4967296 +
6478 user.dwLowDateTime*1e-7),
6479 (double)(kernel.dwHighDateTime*429.4967296 +
6480 kernel.dwLowDateTime*1e-7),
6481 (double)0,
6482 (double)0,
6483 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006484}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006485#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006486
6487#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006488PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006489"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006491#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006494#ifdef HAVE_GETSID
6495PyDoc_STRVAR(posix_getsid__doc__,
6496"getsid(pid) -> sid\n\n\
6497Call the system call getsid().");
6498
6499static PyObject *
6500posix_getsid(PyObject *self, PyObject *args)
6501{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006502 pid_t pid;
6503 int sid;
6504 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6505 return NULL;
6506 sid = getsid(pid);
6507 if (sid < 0)
6508 return posix_error();
6509 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006510}
6511#endif /* HAVE_GETSID */
6512
6513
Guido van Rossumb6775db1994-08-01 11:34:53 +00006514#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006516"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006518
Barry Warsaw53699e91996-12-10 23:23:01 +00006519static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006520posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006521{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006522 if (setsid() < 0)
6523 return posix_error();
6524 Py_INCREF(Py_None);
6525 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006526}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006527#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006528
Guido van Rossumb6775db1994-08-01 11:34:53 +00006529#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006532Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006533
Barry Warsaw53699e91996-12-10 23:23:01 +00006534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006535posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006536{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006537 pid_t pid;
6538 int pgrp;
6539 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6540 return NULL;
6541 if (setpgid(pid, pgrp) < 0)
6542 return posix_error();
6543 Py_INCREF(Py_None);
6544 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006545}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006546#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006548
Guido van Rossumb6775db1994-08-01 11:34:53 +00006549#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006551"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006552Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006553
Barry Warsaw53699e91996-12-10 23:23:01 +00006554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006555posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006556{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006557 int fd;
6558 pid_t pgid;
6559 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6560 return NULL;
6561 pgid = tcgetpgrp(fd);
6562 if (pgid < 0)
6563 return posix_error();
6564 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006565}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006566#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006568
Guido van Rossumb6775db1994-08-01 11:34:53 +00006569#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006570PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006571"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006572Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006573
Barry Warsaw53699e91996-12-10 23:23:01 +00006574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006575posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006576{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006577 int fd;
6578 pid_t pgid;
6579 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6580 return NULL;
6581 if (tcsetpgrp(fd, pgid) < 0)
6582 return posix_error();
6583 Py_INCREF(Py_None);
6584 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006585}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006586#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006587
Guido van Rossum687dd131993-05-17 08:34:16 +00006588/* Functions acting on file descriptors */
6589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006590PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006591"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006593
Barry Warsaw53699e91996-12-10 23:23:01 +00006594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006595posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006596{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006597 char *file = NULL;
6598 int flag;
6599 int mode = 0777;
6600 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006601
6602#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006603 PyUnicodeObject *po;
6604 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6605 Py_BEGIN_ALLOW_THREADS
6606 /* PyUnicode_AS_UNICODE OK without thread
6607 lock as it is a simple dereference. */
6608 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6609 Py_END_ALLOW_THREADS
6610 if (fd < 0)
6611 return posix_error();
6612 return PyInt_FromLong((long)fd);
6613 }
6614 /* Drop the argument parsing error as narrow strings
6615 are also valid. */
6616 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006617#endif
6618
Victor Stinnerd6f85422010-05-05 23:33:33 +00006619 if (!PyArg_ParseTuple(args, "eti|i",
6620 Py_FileSystemDefaultEncoding, &file,
6621 &flag, &mode))
6622 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006623
Victor Stinnerd6f85422010-05-05 23:33:33 +00006624 Py_BEGIN_ALLOW_THREADS
6625 fd = open(file, flag, mode);
6626 Py_END_ALLOW_THREADS
6627 if (fd < 0)
6628 return posix_error_with_allocated_filename(file);
6629 PyMem_Free(file);
6630 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006631}
6632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006634PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006635"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006637
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006638/*
6639The underscore at end of function name avoids a name clash with the libc
6640function posix_close.
6641*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006642static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006643posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006644{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006645 int fd, res;
6646 if (!PyArg_ParseTuple(args, "i:close", &fd))
6647 return NULL;
6648 if (!_PyVerify_fd(fd))
6649 return posix_error();
6650 Py_BEGIN_ALLOW_THREADS
6651 res = close(fd);
6652 Py_END_ALLOW_THREADS
6653 if (res < 0)
6654 return posix_error();
6655 Py_INCREF(Py_None);
6656 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006657}
6658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006659
Victor Stinnerd6f85422010-05-05 23:33:33 +00006660PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006661"closerange(fd_low, fd_high)\n\n\
6662Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6663
6664static PyObject *
6665posix_closerange(PyObject *self, PyObject *args)
6666{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006667 int fd_from, fd_to, i;
6668 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6669 return NULL;
6670 Py_BEGIN_ALLOW_THREADS
6671 for (i = fd_from; i < fd_to; i++)
6672 if (_PyVerify_fd(i))
6673 close(i);
6674 Py_END_ALLOW_THREADS
6675 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006676}
6677
6678
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006679PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006680"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006681Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006682
Barry Warsaw53699e91996-12-10 23:23:01 +00006683static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006684posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006685{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006686 int fd;
6687 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6688 return NULL;
6689 if (!_PyVerify_fd(fd))
6690 return posix_error();
6691 Py_BEGIN_ALLOW_THREADS
6692 fd = dup(fd);
6693 Py_END_ALLOW_THREADS
6694 if (fd < 0)
6695 return posix_error();
6696 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006697}
6698
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006699
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006700PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006701"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006702Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006703
Barry Warsaw53699e91996-12-10 23:23:01 +00006704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006705posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006706{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006707 int fd, fd2, res;
6708 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6709 return NULL;
6710 if (!_PyVerify_fd_dup2(fd, fd2))
6711 return posix_error();
6712 Py_BEGIN_ALLOW_THREADS
6713 res = dup2(fd, fd2);
6714 Py_END_ALLOW_THREADS
6715 if (res < 0)
6716 return posix_error();
6717 Py_INCREF(Py_None);
6718 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006719}
6720
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006721
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006723"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006724Set the current position of a file descriptor.\n\
6725Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006726
Barry Warsaw53699e91996-12-10 23:23:01 +00006727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006728posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006729{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006730 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006731#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006732 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006733#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006734 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006735#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006736 PyObject *posobj;
6737 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6738 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006739#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006740 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6741 switch (how) {
6742 case 0: how = SEEK_SET; break;
6743 case 1: how = SEEK_CUR; break;
6744 case 2: how = SEEK_END; break;
6745 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006746#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006747
6748#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006749 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006750#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006751 pos = PyLong_Check(posobj) ?
6752 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006753#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006754 if (PyErr_Occurred())
6755 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006756
Victor Stinnerd6f85422010-05-05 23:33:33 +00006757 if (!_PyVerify_fd(fd))
6758 return posix_error();
6759 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006760#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006761 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006762#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006763 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006764#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006765 Py_END_ALLOW_THREADS
6766 if (res < 0)
6767 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006768
6769#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006770 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006771#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006772 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006773#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006774}
6775
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006777PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006778"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006779Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006780
Barry Warsaw53699e91996-12-10 23:23:01 +00006781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006782posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006783{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006784 int fd, size, n;
6785 PyObject *buffer;
6786 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6787 return NULL;
6788 if (size < 0) {
6789 errno = EINVAL;
6790 return posix_error();
6791 }
6792 buffer = PyString_FromStringAndSize((char *)NULL, size);
6793 if (buffer == NULL)
6794 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006795 if (!_PyVerify_fd(fd)) {
6796 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006797 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006798 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006799 Py_BEGIN_ALLOW_THREADS
6800 n = read(fd, PyString_AsString(buffer), size);
6801 Py_END_ALLOW_THREADS
6802 if (n < 0) {
6803 Py_DECREF(buffer);
6804 return posix_error();
6805 }
6806 if (n != size)
6807 _PyString_Resize(&buffer, n);
6808 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006809}
6810
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006812PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006813"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006815
Barry Warsaw53699e91996-12-10 23:23:01 +00006816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006817posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006818{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006819 Py_buffer pbuf;
6820 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006821 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006822
Victor Stinnerd6f85422010-05-05 23:33:33 +00006823 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6824 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006825 if (!_PyVerify_fd(fd)) {
6826 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006827 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006828 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006829 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006830 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006831#if defined(MS_WIN64) || defined(MS_WINDOWS)
6832 if (len > INT_MAX)
6833 len = INT_MAX;
6834 size = write(fd, pbuf.buf, (int)len);
6835#else
6836 size = write(fd, pbuf.buf, len);
6837#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006838 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006839 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006840 if (size < 0)
6841 return posix_error();
6842 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006843}
6844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006845
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006846PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006847"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006849
Barry Warsaw53699e91996-12-10 23:23:01 +00006850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006851posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006852{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006853 int fd;
6854 STRUCT_STAT st;
6855 int res;
6856 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6857 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006858#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006859 /* on OpenVMS we must ensure that all bytes are written to the file */
6860 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006861#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006862 if (!_PyVerify_fd(fd))
6863 return posix_error();
6864 Py_BEGIN_ALLOW_THREADS
6865 res = FSTAT(fd, &st);
6866 Py_END_ALLOW_THREADS
6867 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006868#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006869 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006870#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006871 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006872#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006873 }
Tim Peters5aa91602002-01-30 05:46:57 +00006874
Victor Stinnerd6f85422010-05-05 23:33:33 +00006875 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006876}
6877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006878
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006879PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006880"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006882
Barry Warsaw53699e91996-12-10 23:23:01 +00006883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006884posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006885{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006886 int fd;
6887 char *orgmode = "r";
6888 int bufsize = -1;
6889 FILE *fp;
6890 PyObject *f;
6891 char *mode;
6892 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6893 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006894
Victor Stinnerd6f85422010-05-05 23:33:33 +00006895 /* Sanitize mode. See fileobject.c */
6896 mode = PyMem_MALLOC(strlen(orgmode)+3);
6897 if (!mode) {
6898 PyErr_NoMemory();
6899 return NULL;
6900 }
6901 strcpy(mode, orgmode);
6902 if (_PyFile_SanitizeMode(mode)) {
6903 PyMem_FREE(mode);
6904 return NULL;
6905 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006906 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006907 PyMem_FREE(mode);
6908 return posix_error();
6909 }
6910#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6911 {
6912 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006913 const char *msg;
6914 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006915 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6916 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006917 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006918 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006919 EISDIR, msg, "<fdopen>");
6920 if (exc) {
6921 PyErr_SetObject(PyExc_IOError, exc);
6922 Py_DECREF(exc);
6923 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006924 return NULL;
6925 }
6926 }
6927#endif
6928 /* The dummy filename used here must be kept in sync with the value
6929 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6930 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
6931 if (f == NULL) {
6932 PyMem_FREE(mode);
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006933 return NULL;
6934 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006935 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006936#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006937 if (mode[0] == 'a') {
6938 /* try to make sure the O_APPEND flag is set */
6939 int flags;
6940 flags = fcntl(fd, F_GETFL);
6941 if (flags != -1)
6942 fcntl(fd, F_SETFL, flags | O_APPEND);
6943 fp = fdopen(fd, mode);
6944 if (fp == NULL && flags != -1)
6945 /* restore old mode if fdopen failed */
6946 fcntl(fd, F_SETFL, flags);
6947 } else {
6948 fp = fdopen(fd, mode);
6949 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006950#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006951 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006952#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006953 Py_END_ALLOW_THREADS
6954 PyMem_FREE(mode);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006955 if (fp == NULL)
6956 return posix_error();
6957 /* We now know we will succeed, so initialize the file object. */
6958 ((PyFileObject *)f)->f_fp = fp;
6959 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006960 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006961}
6962
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006963PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006964"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006965Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006966connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006967
6968static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006969posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006970{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006971 int fd;
6972 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6973 return NULL;
6974 if (!_PyVerify_fd(fd))
6975 return PyBool_FromLong(0);
6976 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006977}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006978
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006979#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006980PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006981"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006983
Barry Warsaw53699e91996-12-10 23:23:01 +00006984static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006985posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006986{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006987#if defined(PYOS_OS2)
6988 HFILE read, write;
6989 APIRET rc;
6990
Victor Stinnerd6f85422010-05-05 23:33:33 +00006991 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006992 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006993 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006994 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006995 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006996
6997 return Py_BuildValue("(ii)", read, write);
6998#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006999#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007000 int fds[2];
7001 int res;
7002 Py_BEGIN_ALLOW_THREADS
7003 res = pipe(fds);
7004 Py_END_ALLOW_THREADS
7005 if (res != 0)
7006 return posix_error();
7007 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007008#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00007009 HANDLE read, write;
7010 int read_fd, write_fd;
7011 BOOL ok;
7012 Py_BEGIN_ALLOW_THREADS
7013 ok = CreatePipe(&read, &write, NULL, 0);
7014 Py_END_ALLOW_THREADS
7015 if (!ok)
7016 return win32_error("CreatePipe", NULL);
7017 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7018 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7019 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007020#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007021#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007022}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007023#endif /* HAVE_PIPE */
7024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007025
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007026#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007027PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007028"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007029Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Barry Warsaw53699e91996-12-10 23:23:01 +00007031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007032posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007033{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007034 char *filename;
7035 int mode = 0666;
7036 int res;
7037 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7038 return NULL;
7039 Py_BEGIN_ALLOW_THREADS
7040 res = mkfifo(filename, mode);
7041 Py_END_ALLOW_THREADS
7042 if (res < 0)
7043 return posix_error();
7044 Py_INCREF(Py_None);
7045 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007046}
7047#endif
7048
7049
Neal Norwitz11690112002-07-30 01:08:28 +00007050#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007051PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007052"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007053Create a filesystem node (file, device special file or named pipe)\n\
7054named filename. mode specifies both the permissions to use and the\n\
7055type of node to be created, being combined (bitwise OR) with one of\n\
7056S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007057device defines the newly created device special file (probably using\n\
7058os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007059
7060
7061static PyObject *
7062posix_mknod(PyObject *self, PyObject *args)
7063{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007064 char *filename;
7065 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007066 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007067 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007068 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7069 &filename, &mode,
7070 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007071 return NULL;
7072 Py_BEGIN_ALLOW_THREADS
7073 res = mknod(filename, mode, device);
7074 Py_END_ALLOW_THREADS
7075 if (res < 0)
7076 return posix_error();
7077 Py_INCREF(Py_None);
7078 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007079}
7080#endif
7081
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007082#ifdef HAVE_DEVICE_MACROS
7083PyDoc_STRVAR(posix_major__doc__,
7084"major(device) -> major number\n\
7085Extracts a device major number from a raw device number.");
7086
7087static PyObject *
7088posix_major(PyObject *self, PyObject *args)
7089{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007090 dev_t device;
7091 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007092 return NULL;
7093 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007094}
7095
7096PyDoc_STRVAR(posix_minor__doc__,
7097"minor(device) -> minor number\n\
7098Extracts a device minor number from a raw device number.");
7099
7100static PyObject *
7101posix_minor(PyObject *self, PyObject *args)
7102{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007103 dev_t device;
7104 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007105 return NULL;
7106 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007107}
7108
7109PyDoc_STRVAR(posix_makedev__doc__,
7110"makedev(major, minor) -> device number\n\
7111Composes a raw device number from the major and minor device numbers.");
7112
7113static PyObject *
7114posix_makedev(PyObject *self, PyObject *args)
7115{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007116 int major, minor;
7117 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7118 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007119 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007120}
7121#endif /* device macros */
7122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007123
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007124#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007125PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007126"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007128
Barry Warsaw53699e91996-12-10 23:23:01 +00007129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007130posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007131{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007132 int fd;
7133 off_t length;
7134 int res;
7135 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007136
Victor Stinnerd6f85422010-05-05 23:33:33 +00007137 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7138 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007139
7140#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007141 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007142#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007143 length = PyLong_Check(lenobj) ?
7144 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007145#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007146 if (PyErr_Occurred())
7147 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007148
Victor Stinnerd6f85422010-05-05 23:33:33 +00007149 Py_BEGIN_ALLOW_THREADS
7150 res = ftruncate(fd, length);
7151 Py_END_ALLOW_THREADS
7152 if (res < 0)
7153 return posix_error();
7154 Py_INCREF(Py_None);
7155 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007156}
7157#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007158
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007159#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007160PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007161"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007162Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007163
Fred Drake762e2061999-08-26 17:23:54 +00007164/* Save putenv() parameters as values here, so we can collect them when they
7165 * get re-set with another call for the same key. */
7166static PyObject *posix_putenv_garbage;
7167
Tim Peters5aa91602002-01-30 05:46:57 +00007168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007169posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007170{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007171 char *s1, *s2;
7172 char *newenv;
7173 PyObject *newstr;
7174 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007175
Victor Stinnerd6f85422010-05-05 23:33:33 +00007176 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7177 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007178
7179#if defined(PYOS_OS2)
7180 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7181 APIRET rc;
7182
Guido van Rossumd48f2521997-12-05 22:19:34 +00007183 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7184 if (rc != NO_ERROR)
7185 return os2_error(rc);
7186
7187 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7188 APIRET rc;
7189
Guido van Rossumd48f2521997-12-05 22:19:34 +00007190 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7191 if (rc != NO_ERROR)
7192 return os2_error(rc);
7193 } else {
7194#endif
7195
Victor Stinnerd6f85422010-05-05 23:33:33 +00007196 /* XXX This can leak memory -- not easy to fix :-( */
7197 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007198#ifdef MS_WINDOWS
7199 if (_MAX_ENV < (len - 1)) {
7200 PyErr_Format(PyExc_ValueError,
7201 "the environment variable is longer than %u bytes",
7202 _MAX_ENV);
7203 return NULL;
7204 }
7205#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007206 /* len includes space for a trailing \0; the size arg to
7207 PyString_FromStringAndSize does not count that */
7208 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7209 if (newstr == NULL)
7210 return PyErr_NoMemory();
7211 newenv = PyString_AS_STRING(newstr);
7212 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7213 if (putenv(newenv)) {
7214 Py_DECREF(newstr);
7215 posix_error();
7216 return NULL;
7217 }
7218 /* Install the first arg and newstr in posix_putenv_garbage;
7219 * this will cause previous value to be collected. This has to
7220 * happen after the real putenv() call because the old value
7221 * was still accessible until then. */
7222 if (PyDict_SetItem(posix_putenv_garbage,
7223 PyTuple_GET_ITEM(args, 0), newstr)) {
7224 /* really not much we can do; just leak */
7225 PyErr_Clear();
7226 }
7227 else {
7228 Py_DECREF(newstr);
7229 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007230
7231#if defined(PYOS_OS2)
7232 }
7233#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007234 Py_INCREF(Py_None);
7235 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007236}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007237#endif /* putenv */
7238
Guido van Rossumc524d952001-10-19 01:31:59 +00007239#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007240PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007241"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007242Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007243
7244static PyObject *
7245posix_unsetenv(PyObject *self, PyObject *args)
7246{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007247 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007248#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007249 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007250#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007251
Victor Stinnerd6f85422010-05-05 23:33:33 +00007252 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7253 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007254
Charles-François Natali93a11752011-11-27 13:01:35 +01007255#ifdef HAVE_BROKEN_UNSETENV
7256 unsetenv(s1);
7257#else
Victor Stinner53853c32011-11-22 22:20:13 +01007258 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007259 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007260 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007261#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007262
Victor Stinnerd6f85422010-05-05 23:33:33 +00007263 /* Remove the key from posix_putenv_garbage;
7264 * this will cause it to be collected. This has to
7265 * happen after the real unsetenv() call because the
7266 * old value was still accessible until then.
7267 */
7268 if (PyDict_DelItem(posix_putenv_garbage,
7269 PyTuple_GET_ITEM(args, 0))) {
7270 /* really not much we can do; just leak */
7271 PyErr_Clear();
7272 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007273
Victor Stinnerd6f85422010-05-05 23:33:33 +00007274 Py_INCREF(Py_None);
7275 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007276}
7277#endif /* unsetenv */
7278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007279PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007280"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007281Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007282
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007284posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007285{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007286 int code;
7287 char *message;
7288 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7289 return NULL;
7290 message = strerror(code);
7291 if (message == NULL) {
7292 PyErr_SetString(PyExc_ValueError,
7293 "strerror() argument out of range");
7294 return NULL;
7295 }
7296 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007297}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007298
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007299
Guido van Rossumc9641791998-08-04 15:26:23 +00007300#ifdef HAVE_SYS_WAIT_H
7301
Fred Drake106c1a02002-04-23 15:58:02 +00007302#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007303PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007304"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007305Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007306
7307static PyObject *
7308posix_WCOREDUMP(PyObject *self, PyObject *args)
7309{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007310 WAIT_TYPE status;
7311 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007312
Victor Stinnerd6f85422010-05-05 23:33:33 +00007313 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7314 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007315
Victor Stinnerd6f85422010-05-05 23:33:33 +00007316 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007317}
7318#endif /* WCOREDUMP */
7319
7320#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007321PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007322"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007323Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007324job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007325
7326static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007327posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007328{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007329 WAIT_TYPE status;
7330 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007331
Victor Stinnerd6f85422010-05-05 23:33:33 +00007332 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7333 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007334
Victor Stinnerd6f85422010-05-05 23:33:33 +00007335 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007336}
7337#endif /* WIFCONTINUED */
7338
Guido van Rossumc9641791998-08-04 15:26:23 +00007339#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007340PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007341"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007342Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007343
7344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007345posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007346{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007347 WAIT_TYPE status;
7348 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007349
Victor Stinnerd6f85422010-05-05 23:33:33 +00007350 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7351 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007352
Victor Stinnerd6f85422010-05-05 23:33:33 +00007353 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007354}
7355#endif /* WIFSTOPPED */
7356
7357#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007358PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007359"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007360Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007361
7362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007363posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007364{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007365 WAIT_TYPE status;
7366 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007367
Victor Stinnerd6f85422010-05-05 23:33:33 +00007368 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7369 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007370
Victor Stinnerd6f85422010-05-05 23:33:33 +00007371 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007372}
7373#endif /* WIFSIGNALED */
7374
7375#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007377"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007378Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007379system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007380
7381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007382posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007383{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007384 WAIT_TYPE status;
7385 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007386
Victor Stinnerd6f85422010-05-05 23:33:33 +00007387 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7388 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007389
Victor Stinnerd6f85422010-05-05 23:33:33 +00007390 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007391}
7392#endif /* WIFEXITED */
7393
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007394#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007395PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007396"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007397Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007398
7399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007400posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007401{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007402 WAIT_TYPE status;
7403 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007404
Victor Stinnerd6f85422010-05-05 23:33:33 +00007405 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7406 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007407
Victor Stinnerd6f85422010-05-05 23:33:33 +00007408 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007409}
7410#endif /* WEXITSTATUS */
7411
7412#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007413PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007414"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007415Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007416value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007417
7418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007419posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007420{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007421 WAIT_TYPE status;
7422 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007423
Victor Stinnerd6f85422010-05-05 23:33:33 +00007424 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7425 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007426
Victor Stinnerd6f85422010-05-05 23:33:33 +00007427 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007428}
7429#endif /* WTERMSIG */
7430
7431#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007432PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007433"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007434Return the signal that stopped the process that provided\n\
7435the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007436
7437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007438posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007439{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007440 WAIT_TYPE status;
7441 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007442
Victor Stinnerd6f85422010-05-05 23:33:33 +00007443 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7444 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007445
Victor Stinnerd6f85422010-05-05 23:33:33 +00007446 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007447}
7448#endif /* WSTOPSIG */
7449
7450#endif /* HAVE_SYS_WAIT_H */
7451
7452
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007453#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007454#ifdef _SCO_DS
7455/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7456 needed definitions in sys/statvfs.h */
7457#define _SVID3
7458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007459#include <sys/statvfs.h>
7460
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007461static PyObject*
7462_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007463 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7464 if (v == NULL)
7465 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007466
7467#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007468 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7469 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7470 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7471 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7472 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7473 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7474 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7475 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7476 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7477 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007478#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007479 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7480 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7481 PyStructSequence_SET_ITEM(v, 2,
7482 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7483 PyStructSequence_SET_ITEM(v, 3,
7484 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7485 PyStructSequence_SET_ITEM(v, 4,
7486 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7487 PyStructSequence_SET_ITEM(v, 5,
7488 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7489 PyStructSequence_SET_ITEM(v, 6,
7490 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7491 PyStructSequence_SET_ITEM(v, 7,
7492 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7493 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7494 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007495#endif
7496
Victor Stinnerd6f85422010-05-05 23:33:33 +00007497 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007498}
7499
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007500PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007501"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007502Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007503
7504static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007505posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007506{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007507 int fd, res;
7508 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007509
Victor Stinnerd6f85422010-05-05 23:33:33 +00007510 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7511 return NULL;
7512 Py_BEGIN_ALLOW_THREADS
7513 res = fstatvfs(fd, &st);
7514 Py_END_ALLOW_THREADS
7515 if (res != 0)
7516 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007517
Victor Stinnerd6f85422010-05-05 23:33:33 +00007518 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007519}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007520#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007521
7522
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007523#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007524#include <sys/statvfs.h>
7525
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007526PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007527"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007528Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007529
7530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007531posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007532{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007533 char *path;
7534 int res;
7535 struct statvfs st;
7536 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7537 return NULL;
7538 Py_BEGIN_ALLOW_THREADS
7539 res = statvfs(path, &st);
7540 Py_END_ALLOW_THREADS
7541 if (res != 0)
7542 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007543
Victor Stinnerd6f85422010-05-05 23:33:33 +00007544 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007545}
7546#endif /* HAVE_STATVFS */
7547
7548
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007549#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007550PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007551"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007552Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007553The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007554or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555
7556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007557posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007558{
7559 PyObject *result = NULL;
7560 char *dir = NULL;
7561 char *pfx = NULL;
7562 char *name;
7563
7564 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007565 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007566
7567 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007568 "tempnam is a potential security risk to your program") < 0)
7569 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007570
Antoine Pitroub0614612011-01-02 20:04:52 +00007571 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7572 "use the tempfile module", 1) < 0)
7573 return NULL;
7574
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007575#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007576 name = _tempnam(dir, pfx);
7577#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007578 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007579#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007580 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007581 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007582 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007583 free(name);
7584 return result;
7585}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007586#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007587
7588
7589#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007590PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007591"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007592Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007593
7594static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007595posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007596{
7597 FILE *fp;
7598
Antoine Pitroub0614612011-01-02 20:04:52 +00007599 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7600 "use the tempfile module", 1) < 0)
7601 return NULL;
7602
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007603 fp = tmpfile();
7604 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007605 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007606 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007607}
7608#endif
7609
7610
7611#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007612PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007613"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007614Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007615
7616static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007617posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007618{
7619 char buffer[L_tmpnam];
7620 char *name;
7621
Skip Montanaro95618b52001-08-18 18:52:10 +00007622 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007623 "tmpnam is a potential security risk to your program") < 0)
7624 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007625
Antoine Pitroub0614612011-01-02 20:04:52 +00007626 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7627 "use the tempfile module", 1) < 0)
7628 return NULL;
7629
Greg Wardb48bc172000-03-01 21:51:56 +00007630#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631 name = tmpnam_r(buffer);
7632#else
7633 name = tmpnam(buffer);
7634#endif
7635 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007636 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007637#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007638 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007639#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007640 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007641#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007642 );
7643 PyErr_SetObject(PyExc_OSError, err);
7644 Py_XDECREF(err);
7645 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007646 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007647 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007648}
7649#endif
7650
7651
Fred Drakec9680921999-12-13 16:37:25 +00007652/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7653 * It maps strings representing configuration variable names to
7654 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007655 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007656 * rarely-used constants. There are three separate tables that use
7657 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007658 *
7659 * This code is always included, even if none of the interfaces that
7660 * need it are included. The #if hackery needed to avoid it would be
7661 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007662 */
7663struct constdef {
7664 char *name;
7665 long value;
7666};
7667
Fred Drake12c6e2d1999-12-14 21:25:03 +00007668static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007669conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007670 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007671{
7672 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007673 *valuep = PyInt_AS_LONG(arg);
7674 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007675 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007676 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007677 /* look up the value in the table using a binary search */
7678 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007679 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007680 size_t hi = tablesize;
7681 int cmp;
7682 char *confname = PyString_AS_STRING(arg);
7683 while (lo < hi) {
7684 mid = (lo + hi) / 2;
7685 cmp = strcmp(confname, table[mid].name);
7686 if (cmp < 0)
7687 hi = mid;
7688 else if (cmp > 0)
7689 lo = mid + 1;
7690 else {
7691 *valuep = table[mid].value;
7692 return 1;
7693 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007694 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007695 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007696 }
7697 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007698 PyErr_SetString(PyExc_TypeError,
7699 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007700 return 0;
7701}
7702
7703
7704#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7705static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007706#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007708#endif
7709#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007711#endif
Fred Drakec9680921999-12-13 16:37:25 +00007712#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007713 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007714#endif
7715#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007716 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007717#endif
7718#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007719 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007720#endif
7721#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007722 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007723#endif
7724#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007725 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007726#endif
7727#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007728 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007729#endif
7730#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007731 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007732#endif
7733#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007735#endif
7736#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007737 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007738#endif
7739#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007740 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007741#endif
7742#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007743 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007744#endif
7745#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007746 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007747#endif
7748#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007749 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007750#endif
7751#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007752 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007753#endif
7754#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007755 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007756#endif
7757};
7758
Fred Drakec9680921999-12-13 16:37:25 +00007759static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007760conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007761{
7762 return conv_confname(arg, valuep, posix_constants_pathconf,
7763 sizeof(posix_constants_pathconf)
7764 / sizeof(struct constdef));
7765}
7766#endif
7767
7768#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007769PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007770"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007771Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007772If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007773
7774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007775posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007776{
7777 PyObject *result = NULL;
7778 int name, fd;
7779
Fred Drake12c6e2d1999-12-14 21:25:03 +00007780 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7781 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007782 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007783
Stefan Krah93f7a322010-11-26 17:35:50 +00007784 errno = 0;
7785 limit = fpathconf(fd, name);
7786 if (limit == -1 && errno != 0)
7787 posix_error();
7788 else
7789 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007790 }
7791 return result;
7792}
7793#endif
7794
7795
7796#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007797PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007798"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007799Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007800If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007801
7802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007803posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007804{
7805 PyObject *result = NULL;
7806 int name;
7807 char *path;
7808
7809 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7810 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007811 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007812
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 errno = 0;
7814 limit = pathconf(path, name);
7815 if (limit == -1 && errno != 0) {
7816 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007817 /* could be a path or name problem */
7818 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007819 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007820 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007821 }
7822 else
7823 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007824 }
7825 return result;
7826}
7827#endif
7828
7829#ifdef HAVE_CONFSTR
7830static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007831#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007832 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007833#endif
7834#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007835 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007836#endif
7837#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007838 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007839#endif
7840#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007841 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007842#endif
7843#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007844 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007845#endif
Fred Drakec9680921999-12-13 16:37:25 +00007846#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007847 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007848#endif
7849#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007850 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007851#endif
7852#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007853 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007854#endif
7855#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007856 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007857#endif
7858#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007859 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007860#endif
7861#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007862 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007863#endif
7864#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007865 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007866#endif
7867#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007868 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007869#endif
Fred Draked86ed291999-12-15 15:34:33 +00007870#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007871 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007872#endif
Fred Drakec9680921999-12-13 16:37:25 +00007873#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007874 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007875#endif
Fred Draked86ed291999-12-15 15:34:33 +00007876#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007877 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007878#endif
7879#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007880 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007881#endif
7882#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007883 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007884#endif
7885#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007886 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007887#endif
Fred Drakec9680921999-12-13 16:37:25 +00007888#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007889 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007890#endif
7891#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007892 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007893#endif
7894#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007895 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007896#endif
7897#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007898 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007899#endif
7900#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007901 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007902#endif
7903#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007904 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007905#endif
7906#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007907 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007908#endif
7909#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007910 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007911#endif
7912#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007913 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007914#endif
7915#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007916 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007917#endif
7918#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007919 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007920#endif
7921#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007922 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007923#endif
7924#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007925 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007926#endif
7927#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007928 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007929#endif
7930#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007931 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007932#endif
7933#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007934 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007935#endif
Fred Draked86ed291999-12-15 15:34:33 +00007936#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007937 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007938#endif
7939#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007940 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007941#endif
7942#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007943 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007944#endif
7945#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007946 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007947#endif
7948#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007949 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007950#endif
7951#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007952 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007953#endif
7954#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007955 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007956#endif
7957#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007958 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007959#endif
7960#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007961 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007962#endif
7963#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007964 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007965#endif
7966#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007967 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007968#endif
7969#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007970 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007971#endif
7972#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007973 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007974#endif
Fred Drakec9680921999-12-13 16:37:25 +00007975};
7976
7977static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007978conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007979{
7980 return conv_confname(arg, valuep, posix_constants_confstr,
7981 sizeof(posix_constants_confstr)
7982 / sizeof(struct constdef));
7983}
7984
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007985PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007986"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007987Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007988
7989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007990posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007991{
7992 PyObject *result = NULL;
7993 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007994 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007995
7996 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007997 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007998
Victor Stinnerd6f85422010-05-05 23:33:33 +00007999 errno = 0;
8000 len = confstr(name, buffer, sizeof(buffer));
8001 if (len == 0) {
8002 if (errno) {
8003 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008004 }
8005 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008006 result = Py_None;
8007 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00008008 }
8009 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00008010 else {
8011 if ((unsigned int)len >= sizeof(buffer)) {
8012 result = PyString_FromStringAndSize(NULL, len-1);
8013 if (result != NULL)
8014 confstr(name, PyString_AS_STRING(result), len);
8015 }
8016 else
8017 result = PyString_FromStringAndSize(buffer, len-1);
8018 }
8019 }
Fred Drakec9680921999-12-13 16:37:25 +00008020 return result;
8021}
8022#endif
8023
8024
8025#ifdef HAVE_SYSCONF
8026static struct constdef posix_constants_sysconf[] = {
8027#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008028 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008029#endif
8030#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008031 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008032#endif
8033#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008034 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008035#endif
8036#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008037 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008038#endif
8039#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008040 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008041#endif
8042#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008043 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008044#endif
8045#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008046 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008047#endif
8048#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008049 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008050#endif
8051#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008052 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008053#endif
8054#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008055 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008056#endif
Fred Draked86ed291999-12-15 15:34:33 +00008057#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008058 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008059#endif
8060#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008061 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008062#endif
Fred Drakec9680921999-12-13 16:37:25 +00008063#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008064 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008065#endif
Fred Drakec9680921999-12-13 16:37:25 +00008066#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008067 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008068#endif
8069#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008070 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008071#endif
8072#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008073 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008074#endif
8075#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008076 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008077#endif
8078#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008079 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008080#endif
Fred Draked86ed291999-12-15 15:34:33 +00008081#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008082 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008083#endif
Fred Drakec9680921999-12-13 16:37:25 +00008084#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008085 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008086#endif
8087#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008088 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008089#endif
8090#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008091 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008092#endif
8093#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008094 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008095#endif
8096#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008097 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008098#endif
Fred Draked86ed291999-12-15 15:34:33 +00008099#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008100 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008101#endif
Fred Drakec9680921999-12-13 16:37:25 +00008102#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008103 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008104#endif
8105#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008106 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008107#endif
8108#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008109 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008110#endif
8111#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008112 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008113#endif
8114#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008115 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008116#endif
8117#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008118 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008119#endif
8120#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008121 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008122#endif
8123#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008124 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008125#endif
8126#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008127 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008128#endif
8129#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008130 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008131#endif
8132#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008133 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008134#endif
8135#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008136 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008137#endif
8138#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008139 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008140#endif
8141#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008142 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008143#endif
8144#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008145 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008146#endif
8147#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008148 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008149#endif
8150#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008151 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008152#endif
8153#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008154 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008155#endif
8156#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008157 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008158#endif
8159#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008160 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008161#endif
8162#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008163 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008164#endif
8165#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008166 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008167#endif
8168#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008169 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008170#endif
Fred Draked86ed291999-12-15 15:34:33 +00008171#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008172 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008173#endif
Fred Drakec9680921999-12-13 16:37:25 +00008174#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008175 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008176#endif
8177#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008178 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008179#endif
8180#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008181 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008182#endif
Fred Draked86ed291999-12-15 15:34:33 +00008183#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008184 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008185#endif
Fred Drakec9680921999-12-13 16:37:25 +00008186#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008187 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008188#endif
Fred Draked86ed291999-12-15 15:34:33 +00008189#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008190 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008191#endif
8192#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008193 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008194#endif
Fred Drakec9680921999-12-13 16:37:25 +00008195#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008196 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008197#endif
8198#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008199 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008200#endif
8201#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008202 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008203#endif
8204#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008205 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008206#endif
Fred Draked86ed291999-12-15 15:34:33 +00008207#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008208 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008209#endif
Fred Drakec9680921999-12-13 16:37:25 +00008210#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008211 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008212#endif
8213#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008214 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008215#endif
8216#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008217 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008218#endif
8219#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008220 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008221#endif
8222#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008223 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008224#endif
8225#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008226 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008227#endif
8228#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008229 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008230#endif
Fred Draked86ed291999-12-15 15:34:33 +00008231#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008232 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008233#endif
Fred Drakec9680921999-12-13 16:37:25 +00008234#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008235 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008236#endif
8237#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008238 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008239#endif
Fred Draked86ed291999-12-15 15:34:33 +00008240#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008241 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008242#endif
Fred Drakec9680921999-12-13 16:37:25 +00008243#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008244 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008245#endif
8246#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008247 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008248#endif
8249#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008250 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008251#endif
8252#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008253 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008254#endif
8255#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008256 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008257#endif
8258#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008259 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008260#endif
8261#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008262 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008263#endif
8264#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008265 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008266#endif
8267#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008268 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008269#endif
Fred Draked86ed291999-12-15 15:34:33 +00008270#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008271 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008272#endif
8273#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008274 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008275#endif
Fred Drakec9680921999-12-13 16:37:25 +00008276#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008277 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008278#endif
8279#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008280 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008281#endif
8282#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008283 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008284#endif
8285#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008286 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008287#endif
8288#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008289 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008290#endif
8291#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008292 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008293#endif
8294#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008295 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008296#endif
8297#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008298 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008299#endif
8300#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008301 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008302#endif
8303#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008304 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008305#endif
8306#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008307 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008308#endif
8309#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008310 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008311#endif
8312#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008313 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008314#endif
8315#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008316 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008317#endif
8318#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008319 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008320#endif
8321#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008322 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008323#endif
8324#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008325 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008326#endif
8327#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008328 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008329#endif
8330#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008331 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008332#endif
8333#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008334 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008335#endif
8336#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008337 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008338#endif
8339#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008340 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008341#endif
8342#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008343 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008344#endif
8345#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008346 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008347#endif
8348#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008349 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008350#endif
8351#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008352 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008353#endif
8354#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008355 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008356#endif
8357#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008358 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008359#endif
8360#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008361 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008362#endif
8363#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008364 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008365#endif
8366#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008367 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008368#endif
8369#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008370 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008371#endif
8372#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008373 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008374#endif
8375#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008376 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008377#endif
8378#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008379 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008380#endif
Fred Draked86ed291999-12-15 15:34:33 +00008381#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008382 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008383#endif
Fred Drakec9680921999-12-13 16:37:25 +00008384#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008385 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008386#endif
8387#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008388 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008389#endif
8390#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008391 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008392#endif
8393#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008394 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008395#endif
8396#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008397 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008398#endif
8399#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008400 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008401#endif
8402#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008403 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008404#endif
8405#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008406 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008407#endif
8408#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008409 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008410#endif
8411#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008412 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008413#endif
8414#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008415 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008416#endif
8417#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008418 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008419#endif
8420#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008421 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008422#endif
8423#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008424 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008425#endif
8426#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008427 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008428#endif
8429#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008430 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008431#endif
8432#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008433 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008434#endif
8435#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008436 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008437#endif
8438#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008439 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008440#endif
8441#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008442 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008443#endif
8444#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008445 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008446#endif
8447#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008448 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008449#endif
8450#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008451 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008452#endif
8453#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008454 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008455#endif
8456#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008457 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008458#endif
8459#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008460 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008461#endif
8462#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008463 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008464#endif
8465#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008466 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008467#endif
8468#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008469 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008470#endif
8471#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008472 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008473#endif
8474#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008475 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008476#endif
8477#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008478 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008479#endif
8480#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008481 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008482#endif
8483#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008484 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008485#endif
8486#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008487 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008488#endif
8489#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008490 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008491#endif
8492#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008493 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008494#endif
8495#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008496 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008497#endif
8498#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008499 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008500#endif
8501#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008502 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008503#endif
8504#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008505 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008506#endif
8507#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008508 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008509#endif
8510#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008511 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008512#endif
8513#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008514 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008515#endif
8516#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008517 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008518#endif
8519};
8520
8521static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008522conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008523{
8524 return conv_confname(arg, valuep, posix_constants_sysconf,
8525 sizeof(posix_constants_sysconf)
8526 / sizeof(struct constdef));
8527}
8528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008529PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008530"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008531Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008532
8533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008534posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008535{
8536 PyObject *result = NULL;
8537 int name;
8538
8539 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008540 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008541
Victor Stinner862490a2010-05-06 00:03:44 +00008542 errno = 0;
8543 value = sysconf(name);
8544 if (value == -1 && errno != 0)
8545 posix_error();
8546 else
8547 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008548 }
8549 return result;
8550}
8551#endif
8552
8553
Fred Drakebec628d1999-12-15 18:31:10 +00008554/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008555 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008556 * the exported dictionaries that are used to publish information about the
8557 * names available on the host platform.
8558 *
8559 * Sorting the table at runtime ensures that the table is properly ordered
8560 * when used, even for platforms we're not able to test on. It also makes
8561 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008562 */
Fred Drakebec628d1999-12-15 18:31:10 +00008563
8564static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008565cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008566{
8567 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008568 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008569 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008570 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008571
8572 return strcmp(c1->name, c2->name);
8573}
8574
8575static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008576setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008577 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008578{
Fred Drakebec628d1999-12-15 18:31:10 +00008579 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008580 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008581 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8582 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008583 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008584 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008585
Barry Warsaw3155db32000-04-13 15:20:40 +00008586 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008587 PyObject *o = PyInt_FromLong(table[i].value);
8588 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8589 Py_XDECREF(o);
8590 Py_DECREF(d);
8591 return -1;
8592 }
8593 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008594 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008595 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008596}
8597
Fred Drakebec628d1999-12-15 18:31:10 +00008598/* Return -1 on failure, 0 on success. */
8599static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008600setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008601{
8602#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008603 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008604 sizeof(posix_constants_pathconf)
8605 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008606 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008607 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008608#endif
8609#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008610 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008611 sizeof(posix_constants_confstr)
8612 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008613 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008614 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008615#endif
8616#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008617 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008618 sizeof(posix_constants_sysconf)
8619 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008620 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008621 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008622#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008623 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008624}
Fred Draked86ed291999-12-15 15:34:33 +00008625
8626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008627PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008628"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008629Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008630in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008631
8632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008633posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008634{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008635 abort();
8636 /*NOTREACHED*/
8637 Py_FatalError("abort() called from Python code didn't abort!");
8638 return NULL;
8639}
Fred Drakebec628d1999-12-15 18:31:10 +00008640
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008641#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008642PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008643"startfile(filepath [, operation]) - Start a file with its associated\n\
8644application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008645\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008646When \"operation\" is not specified or \"open\", this acts like\n\
8647double-clicking the file in Explorer, or giving the file name as an\n\
8648argument to the DOS \"start\" command: the file is opened with whatever\n\
8649application (if any) its extension is associated.\n\
8650When another \"operation\" is given, it specifies what should be done with\n\
8651the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008652\n\
8653startfile returns as soon as the associated application is launched.\n\
8654There is no option to wait for the application to close, and no way\n\
8655to retrieve the application's exit status.\n\
8656\n\
8657The filepath is relative to the current directory. If you want to use\n\
8658an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008659the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008660
8661static PyObject *
8662win32_startfile(PyObject *self, PyObject *args)
8663{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008664 char *filepath;
8665 char *operation = NULL;
8666 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008667
Victor Stinnerd6f85422010-05-05 23:33:33 +00008668 PyObject *unipath, *woperation = NULL;
8669 if (!PyArg_ParseTuple(args, "U|s:startfile",
8670 &unipath, &operation)) {
8671 PyErr_Clear();
8672 goto normal;
8673 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008674
Victor Stinnerd6f85422010-05-05 23:33:33 +00008675 if (operation) {
8676 woperation = PyUnicode_DecodeASCII(operation,
8677 strlen(operation), NULL);
8678 if (!woperation) {
8679 PyErr_Clear();
8680 operation = NULL;
8681 goto normal;
8682 }
8683 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008684
Victor Stinnerd6f85422010-05-05 23:33:33 +00008685 Py_BEGIN_ALLOW_THREADS
8686 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8687 PyUnicode_AS_UNICODE(unipath),
8688 NULL, NULL, SW_SHOWNORMAL);
8689 Py_END_ALLOW_THREADS
8690
8691 Py_XDECREF(woperation);
8692 if (rc <= (HINSTANCE)32) {
8693 PyObject *errval = win32_error_unicode("startfile",
8694 PyUnicode_AS_UNICODE(unipath));
8695 return errval;
8696 }
8697 Py_INCREF(Py_None);
8698 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008699
8700normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008701 if (!PyArg_ParseTuple(args, "et|s:startfile",
8702 Py_FileSystemDefaultEncoding, &filepath,
8703 &operation))
8704 return NULL;
8705 Py_BEGIN_ALLOW_THREADS
8706 rc = ShellExecute((HWND)0, operation, filepath,
8707 NULL, NULL, SW_SHOWNORMAL);
8708 Py_END_ALLOW_THREADS
8709 if (rc <= (HINSTANCE)32) {
8710 PyObject *errval = win32_error("startfile", filepath);
8711 PyMem_Free(filepath);
8712 return errval;
8713 }
8714 PyMem_Free(filepath);
8715 Py_INCREF(Py_None);
8716 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008717}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008718#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008719
Martin v. Löwis438b5342002-12-27 10:16:42 +00008720#ifdef HAVE_GETLOADAVG
8721PyDoc_STRVAR(posix_getloadavg__doc__,
8722"getloadavg() -> (float, float, float)\n\n\
8723Return the number of processes in the system run queue averaged over\n\
8724the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8725was unobtainable");
8726
8727static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008728posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008729{
8730 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008731 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008732 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8733 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008734 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008735 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008736}
8737#endif
8738
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008739PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008740"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008741Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008742
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008743static PyObject *
8744posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008745{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008746 Py_ssize_t size;
8747 PyObject *result;
8748 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008749
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008750 /* Read arguments */
8751 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008752 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008753 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008754 return PyErr_Format(PyExc_ValueError,
8755 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008756 result = PyBytes_FromStringAndSize(NULL, size);
8757 if (result == NULL)
8758 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008759
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008760 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8761 PyBytes_GET_SIZE(result));
8762 if (ret == -1) {
8763 Py_DECREF(result);
8764 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008765 }
8766 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008767}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008768
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008769#ifdef HAVE_SETRESUID
8770PyDoc_STRVAR(posix_setresuid__doc__,
8771"setresuid(ruid, euid, suid)\n\n\
8772Set the current process's real, effective, and saved user ids.");
8773
8774static PyObject*
8775posix_setresuid (PyObject *self, PyObject *args)
8776{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008777 uid_t ruid, euid, suid;
8778 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8779 _Py_Uid_Converter, &ruid,
8780 _Py_Uid_Converter, &euid,
8781 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008782 return NULL;
8783 if (setresuid(ruid, euid, suid) < 0)
8784 return posix_error();
8785 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008786}
8787#endif
8788
8789#ifdef HAVE_SETRESGID
8790PyDoc_STRVAR(posix_setresgid__doc__,
8791"setresgid(rgid, egid, sgid)\n\n\
8792Set the current process's real, effective, and saved group ids.");
8793
8794static PyObject*
8795posix_setresgid (PyObject *self, PyObject *args)
8796{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008797 gid_t rgid, egid, sgid;
8798 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8799 _Py_Gid_Converter, &rgid,
8800 _Py_Gid_Converter, &egid,
8801 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008802 return NULL;
8803 if (setresgid(rgid, egid, sgid) < 0)
8804 return posix_error();
8805 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008806}
8807#endif
8808
8809#ifdef HAVE_GETRESUID
8810PyDoc_STRVAR(posix_getresuid__doc__,
8811"getresuid() -> (ruid, euid, suid)\n\n\
8812Get tuple of the current process's real, effective, and saved user ids.");
8813
8814static PyObject*
8815posix_getresuid (PyObject *self, PyObject *noargs)
8816{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008817 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008818 if (getresuid(&ruid, &euid, &suid) < 0)
8819 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008820 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8821 _PyInt_FromUid(euid),
8822 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008823}
8824#endif
8825
8826#ifdef HAVE_GETRESGID
8827PyDoc_STRVAR(posix_getresgid__doc__,
8828"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008829Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008830
8831static PyObject*
8832posix_getresgid (PyObject *self, PyObject *noargs)
8833{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008834 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008835 if (getresgid(&rgid, &egid, &sgid) < 0)
8836 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008837 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8838 _PyInt_FromGid(egid),
8839 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008840}
8841#endif
8842
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008843static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008844 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008845#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008846 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008847#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008848 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008849#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008850 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008851#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008852 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008853#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008854 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008855#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008856#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008857 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008858#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008859#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008860 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008861#endif /* HAVE_LCHMOD */
8862#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008864#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008865#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008866 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008867#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008868#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008869 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008870#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008871#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008872 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008873#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008874#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008875 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008876#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008877#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008878 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008879#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008881#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008882#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008883#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008884 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008885#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8887 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8888 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008889#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008890 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008891#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008892#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008893 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008894#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8896 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8897 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8898 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008899#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008900 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008901#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008902#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008903 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008904#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008905 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008906#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008908#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008909 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8910 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8911 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008912#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008913 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008914#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008915 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008916#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008917 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8918 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008919#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008920#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008921 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8922 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008923#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8925 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008926#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008927#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008928#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008930#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008931#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008933#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008934#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008936#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008937#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008938 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008939#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008940#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008941 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008942#endif /* HAVE_GETEGID */
8943#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008944 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008945#endif /* HAVE_GETEUID */
8946#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008947 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008948#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008949#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008950 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008951#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008953#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008954 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008955#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008956#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008957 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008958#endif /* HAVE_GETPPID */
8959#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008960 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008961#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008962#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008964#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008965#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008966 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008967#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008968#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008969 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008970#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008971#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008972 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008973#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008974#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008975 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008976#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008977 {"popen2", win32_popen2, METH_VARARGS},
8978 {"popen3", win32_popen3, METH_VARARGS},
8979 {"popen4", win32_popen4, METH_VARARGS},
8980 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8981 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008982#else
8983#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008984 {"popen2", os2emx_popen2, METH_VARARGS},
8985 {"popen3", os2emx_popen3, METH_VARARGS},
8986 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008987#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008988#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008989#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008990#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008991 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008992#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008993#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008994 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008995#endif /* HAVE_SETEUID */
8996#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008997 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008998#endif /* HAVE_SETEGID */
8999#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009000 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009001#endif /* HAVE_SETREUID */
9002#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009003 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009004#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009005#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009006 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009007#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009008#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009009 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009010#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009011#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009012 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009013#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00009014#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009015 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00009016#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009017#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009018 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009019#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009020#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009021 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009022#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009023#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009024 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009025#endif /* HAVE_WAIT3 */
9026#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009027 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009028#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009029#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009030 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009031#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009032#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009033 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009034#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009035#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009036 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009037#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009038#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009039 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009040#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009041#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009042 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009043#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009044#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009045 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009046#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009047 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009048 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009049 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9050 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9051 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9052 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9053 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9054 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9055 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9056 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9057 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009058#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009059 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009060#endif
9061#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009062 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009063#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009064#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009066#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009067#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9069 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9070 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009072#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009073 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009074#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009075#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009076 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009077#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009078#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009079 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009080#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009081 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009082#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009083 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009084#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009085#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009086 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009087#endif
9088#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009090#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009091#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009092#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009093 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009094#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009095#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009096 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009097#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009098#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009099 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009100#endif /* WIFSTOPPED */
9101#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009102 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009103#endif /* WIFSIGNALED */
9104#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009105 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009106#endif /* WIFEXITED */
9107#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009108 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009109#endif /* WEXITSTATUS */
9110#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009111 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009112#endif /* WTERMSIG */
9113#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009114 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009115#endif /* WSTOPSIG */
9116#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009117#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009119#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009120#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009122#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009123#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009124 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009125#endif
9126#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009127 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009128#endif
9129#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009131#endif
Fred Drakec9680921999-12-13 16:37:25 +00009132#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009133 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009134#endif
9135#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009136 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009137#endif
9138#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009139 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009140#endif
9141#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009142 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009143#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009145#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009146 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009147 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009148#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009149#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009150 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009151#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009152#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009153 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009154#endif
9155#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009156 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009157#endif
9158#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009159 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009160#endif
9161#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009162 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009163#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009164 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009165 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009166};
9167
9168
Barry Warsaw4a342091996-12-19 23:50:02 +00009169static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009170ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009171{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009172 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009173}
9174
Guido van Rossumd48f2521997-12-05 22:19:34 +00009175#if defined(PYOS_OS2)
9176/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009177static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009178{
9179 APIRET rc;
9180 ULONG values[QSV_MAX+1];
9181 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009182 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009183
9184 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009185 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009186 Py_END_ALLOW_THREADS
9187
9188 if (rc != NO_ERROR) {
9189 os2_error(rc);
9190 return -1;
9191 }
9192
Fred Drake4d1e64b2002-04-15 19:40:07 +00009193 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9194 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9195 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9196 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9197 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9198 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9199 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009200
9201 switch (values[QSV_VERSION_MINOR]) {
9202 case 0: ver = "2.00"; break;
9203 case 10: ver = "2.10"; break;
9204 case 11: ver = "2.11"; break;
9205 case 30: ver = "3.00"; break;
9206 case 40: ver = "4.00"; break;
9207 case 50: ver = "5.00"; break;
9208 default:
Tim Peters885d4572001-11-28 20:27:42 +00009209 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009210 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009211 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009212 ver = &tmp[0];
9213 }
9214
9215 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009216 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009217 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009218
9219 /* Add Indicator of Which Drive was Used to Boot the System */
9220 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9221 tmp[1] = ':';
9222 tmp[2] = '\0';
9223
Fred Drake4d1e64b2002-04-15 19:40:07 +00009224 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009225}
9226#endif
9227
Barry Warsaw4a342091996-12-19 23:50:02 +00009228static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009229all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009230{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009231#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009232 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009233#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009234#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009235 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009236#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009237#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009238 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009239#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009240#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009242#endif
Fred Drakec9680921999-12-13 16:37:25 +00009243#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009244 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009245#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009246#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009247 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009248#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009249#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009250 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009251#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009252#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009253 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009254#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009255#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009256 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009257#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009258#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009259 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009260#endif
9261#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009262 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009263#endif
9264#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009265 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009266#endif
9267#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009268 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009269#endif
9270#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009271 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009272#endif
9273#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009274 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009275#endif
9276#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009277 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009278#endif
9279#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009280 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009281#endif
9282#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009283 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009284#endif
9285#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009286 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009287#endif
9288#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009289 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009290#endif
9291#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009292 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009293#endif
9294#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009295 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009296#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009297#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009298 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009299#endif
9300#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009301 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009302#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009303#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009304 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009305#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009306#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009307 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009308#endif
9309#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009310 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009311#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009312
Tim Peters5aa91602002-01-30 05:46:57 +00009313/* MS Windows */
9314#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009315 /* Don't inherit in child processes. */
9316 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009317#endif
9318#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009319 /* Optimize for short life (keep in memory). */
9320 /* MS forgot to define this one with a non-underscore form too. */
9321 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009322#endif
9323#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009324 /* Automatically delete when last handle is closed. */
9325 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009326#endif
9327#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009328 /* Optimize for random access. */
9329 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009330#endif
9331#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009332 /* Optimize for sequential access. */
9333 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009334#endif
9335
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009336/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009337#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009338 /* Send a SIGIO signal whenever input or output
9339 becomes available on file descriptor */
9340 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009341#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009342#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009343 /* Direct disk access. */
9344 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009345#endif
9346#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009347 /* Must be a directory. */
9348 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009349#endif
9350#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009351 /* Do not follow links. */
9352 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009353#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009354#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009355 /* Do not update the access time. */
9356 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009357#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009358
Victor Stinnerd6f85422010-05-05 23:33:33 +00009359 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009360#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009361 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009362#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009363#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009364 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009365#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009366#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009367 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009368#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009369#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009370 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009371#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009372#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009373 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009374#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009375#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009376 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009377#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009378#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009379 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009380#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009381#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009382 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009383#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009384#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009385 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009386#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009387#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009388 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009389#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009390#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009391 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009392#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009393#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009394 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009395#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009396#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009397 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009398#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009399#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009400 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009401#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009402#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009403 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009404#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009405#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009406 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009407#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009408#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009409 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009410#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009411
Guido van Rossum246bc171999-02-01 23:54:31 +00009412#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009413#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009414 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9415 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9416 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9417 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9418 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9419 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9420 if (ins(d, "P_PM", (long)P_PM)) return -1;
9421 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9422 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9423 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9424 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9425 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9426 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9427 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9428 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9429 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9430 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9431 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9432 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9433 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009434#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009435 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9436 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9437 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9438 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9439 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009440#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009441#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009442
Guido van Rossumd48f2521997-12-05 22:19:34 +00009443#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009444 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009445#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009446 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009447}
9448
9449
Tim Peters5aa91602002-01-30 05:46:57 +00009450#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009451#define INITFUNC initnt
9452#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009453
9454#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009455#define INITFUNC initos2
9456#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009457
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009458#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009459#define INITFUNC initposix
9460#define MODNAME "posix"
9461#endif
9462
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009463PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009464INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009465{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009466 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009467
Victor Stinnerd6f85422010-05-05 23:33:33 +00009468 m = Py_InitModule3(MODNAME,
9469 posix_methods,
9470 posix__doc__);
9471 if (m == NULL)
9472 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009473
Victor Stinnerd6f85422010-05-05 23:33:33 +00009474 /* Initialize environ dictionary */
9475 v = convertenviron();
9476 Py_XINCREF(v);
9477 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9478 return;
9479 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009480
Victor Stinnerd6f85422010-05-05 23:33:33 +00009481 if (all_ins(m))
9482 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009483
Victor Stinnerd6f85422010-05-05 23:33:33 +00009484 if (setup_confname_tables(m))
9485 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009486
Victor Stinnerd6f85422010-05-05 23:33:33 +00009487 Py_INCREF(PyExc_OSError);
9488 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009489
Guido van Rossumb3d39562000-01-31 18:41:26 +00009490#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009491 if (posix_putenv_garbage == NULL)
9492 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009493#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009494
Victor Stinnerd6f85422010-05-05 23:33:33 +00009495 if (!initialized) {
9496 stat_result_desc.name = MODNAME ".stat_result";
9497 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9498 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9499 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9500 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9501 structseq_new = StatResultType.tp_new;
9502 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009503
Victor Stinnerd6f85422010-05-05 23:33:33 +00009504 statvfs_result_desc.name = MODNAME ".statvfs_result";
9505 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009506#ifdef NEED_TICKS_PER_SECOND
9507# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009508 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009509# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009510 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009511# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009512 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009513# endif
9514#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009515 }
9516 Py_INCREF((PyObject*) &StatResultType);
9517 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9518 Py_INCREF((PyObject*) &StatVFSResultType);
9519 PyModule_AddObject(m, "statvfs_result",
9520 (PyObject*) &StatVFSResultType);
9521 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009522
9523#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009524 /*
9525 * Step 2 of weak-linking support on Mac OS X.
9526 *
9527 * The code below removes functions that are not available on the
9528 * currently active platform.
9529 *
9530 * This block allow one to use a python binary that was build on
9531 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9532 * OSX 10.4.
9533 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009534#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009535 if (fstatvfs == NULL) {
9536 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9537 return;
9538 }
9539 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009540#endif /* HAVE_FSTATVFS */
9541
9542#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009543 if (statvfs == NULL) {
9544 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9545 return;
9546 }
9547 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009548#endif /* HAVE_STATVFS */
9549
9550# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009551 if (lchown == NULL) {
9552 if (PyObject_DelAttrString(m, "lchown") == -1) {
9553 return;
9554 }
9555 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009556#endif /* HAVE_LCHOWN */
9557
9558
9559#endif /* __APPLE__ */
9560
Guido van Rossumb6775db1994-08-01 11:34:53 +00009561}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009562
9563#ifdef __cplusplus
9564}
9565#endif
9566
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009567