blob: c4c767e9cdf5881bfcb9ff1149553e7ba22d01b3 [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{
481#ifdef HAVE_LONG_LONG
482 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
483#else
484 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
485#endif
486 if (PyErr_Occurred())
487 return 0;
488 return 1;
489}
490
491#ifdef HAVE_LONG_LONG
492static PyObject *
493_PyInt_FromDev(PY_LONG_LONG v)
494{
495 if (LONG_MIN <= v && v <= LONG_MAX)
496 return PyInt_FromLong((long)v);
497 else
498 return PyLong_FromLongLong(v);
499}
500#else
501# define _PyInt_FromDev PyInt_FromLong
502#endif
503
504#endif
505
506
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000507#if defined _MSC_VER && _MSC_VER >= 1400
508/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov4bb142b2012-12-18 21:27:37 +0200509 * valid and raise an assertion if it isn't.
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000510 * Normally, an invalid fd is likely to be a C program error and therefore
511 * an assertion can be useful, but it does contradict the POSIX standard
512 * which for write(2) states:
513 * "Otherwise, -1 shall be returned and errno set to indicate the error."
514 * "[EBADF] The fildes argument is not a valid file descriptor open for
515 * writing."
516 * Furthermore, python allows the user to enter any old integer
517 * as a fd and should merely raise a python exception on error.
518 * The Microsoft CRT doesn't provide an official way to check for the
519 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000520 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000521 * internal structures involved.
522 * The structures below must be updated for each version of visual studio
523 * according to the file internal.h in the CRT source, until MS comes
524 * up with a less hacky way to do this.
525 * (all of this is to avoid globally modifying the CRT behaviour using
526 * _set_invalid_parameter_handler() and _CrtSetReportMode())
527 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000528/* The actual size of the structure is determined at runtime.
529 * Only the first items must be present.
530 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000531typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000532 intptr_t osfhnd;
533 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000534} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000535
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000536extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000537#define IOINFO_L2E 5
538#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
539#define IOINFO_ARRAYS 64
540#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
541#define FOPEN 0x01
542#define _NO_CONSOLE_FILENO (intptr_t)-2
543
544/* This function emulates what the windows CRT does to validate file handles */
545int
546_PyVerify_fd(int fd)
547{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000548 const int i1 = fd >> IOINFO_L2E;
549 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000550
Victor Stinnerd6f85422010-05-05 23:33:33 +0000551 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000552
Victor Stinnerd6f85422010-05-05 23:33:33 +0000553 /* Determine the actual size of the ioinfo structure,
554 * as used by the CRT loaded in memory
555 */
556 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
557 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
558 }
559 if (sizeof_ioinfo == 0) {
560 /* This should not happen... */
561 goto fail;
562 }
563
564 /* See that it isn't a special CLEAR fileno */
565 if (fd != _NO_CONSOLE_FILENO) {
566 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
567 * we check pointer validity and other info
568 */
569 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
570 /* finally, check that the file is open */
571 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
572 if (info->osfile & FOPEN) {
573 return 1;
574 }
575 }
576 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000577 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000578 errno = EBADF;
579 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000580}
581
582/* the special case of checking dup2. The target fd must be in a sensible range */
583static int
584_PyVerify_fd_dup2(int fd1, int fd2)
585{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000586 if (!_PyVerify_fd(fd1))
587 return 0;
588 if (fd2 == _NO_CONSOLE_FILENO)
589 return 0;
590 if ((unsigned)fd2 < _NHANDLE_)
591 return 1;
592 else
593 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000594}
595#else
596/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
597#define _PyVerify_fd_dup2(A, B) (1)
598#endif
599
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100601#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000602/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100603** environ directly, we must obtain it with _NSGetEnviron(). See also
604** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000605*/
606#include <crt_externs.h>
607static char **environ;
608#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000610#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000611
Barry Warsaw53699e91996-12-10 23:23:01 +0000612static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000613convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000615 PyObject *d;
616 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000617#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000618 APIRET rc;
619 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
620#endif
621 d = PyDict_New();
622 if (d == NULL)
623 return NULL;
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100624#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinnerd6f85422010-05-05 23:33:33 +0000625 if (environ == NULL)
626 environ = *_NSGetEnviron();
627#endif
628 if (environ == NULL)
629 return d;
630 /* This part ignores errors */
631 for (e = environ; *e != NULL; e++) {
632 PyObject *k;
633 PyObject *v;
634 char *p = strchr(*e, '=');
635 if (p == NULL)
636 continue;
637 k = PyString_FromStringAndSize(*e, (int)(p-*e));
638 if (k == NULL) {
639 PyErr_Clear();
640 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000641 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000642 v = PyString_FromString(p+1);
643 if (v == NULL) {
644 PyErr_Clear();
645 Py_DECREF(k);
646 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000647 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000648 if (PyDict_GetItem(d, k) == NULL) {
649 if (PyDict_SetItem(d, k, v) != 0)
650 PyErr_Clear();
651 }
652 Py_DECREF(k);
653 Py_DECREF(v);
654 }
655#if defined(PYOS_OS2)
656 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
657 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
658 PyObject *v = PyString_FromString(buffer);
659 PyDict_SetItemString(d, "BEGINLIBPATH", v);
660 Py_DECREF(v);
661 }
662 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
663 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
664 PyObject *v = PyString_FromString(buffer);
665 PyDict_SetItemString(d, "ENDLIBPATH", v);
666 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000667 }
668#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000669 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670}
671
672
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000673/* Set a POSIX-specific error from errno, and return NULL */
674
Barry Warsawd58d7641998-07-23 16:14:40 +0000675static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000676posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000677{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000678 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679}
Barry Warsawd58d7641998-07-23 16:14:40 +0000680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000681posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000682{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000683 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000684}
685
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000686#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000687static PyObject *
688posix_error_with_unicode_filename(Py_UNICODE* name)
689{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000690 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000691}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000692#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000693
694
Mark Hammondef8b6542001-05-13 08:04:26 +0000695static PyObject *
696posix_error_with_allocated_filename(char* name)
697{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000698 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
699 PyMem_Free(name);
700 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000701}
702
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000703#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000704static PyObject *
705win32_error(char* function, char* filename)
706{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000707 /* XXX We should pass the function name along in the future.
708 (_winreg.c also wants to pass the function name.)
709 This would however require an additional param to the
710 Windows error object, which is non-trivial.
711 */
712 errno = GetLastError();
713 if (filename)
714 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
715 else
716 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000717}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000718
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000719static PyObject *
720win32_error_unicode(char* function, Py_UNICODE* filename)
721{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000722 /* XXX - see win32_error for comments on 'function' */
723 errno = GetLastError();
724 if (filename)
725 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
726 else
727 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000728}
729
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000730static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000731convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000732{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000733 if (PyUnicode_CheckExact(*param))
734 Py_INCREF(*param);
735 else if (PyUnicode_Check(*param))
736 /* For a Unicode subtype that's not a Unicode object,
737 return a true Unicode object with the same data. */
738 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
739 PyUnicode_GET_SIZE(*param));
740 else
741 *param = PyUnicode_FromEncodedObject(*param,
742 Py_FileSystemDefaultEncoding,
743 "strict");
744 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000745}
746
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000747#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000748
Guido van Rossumd48f2521997-12-05 22:19:34 +0000749#if defined(PYOS_OS2)
750/**********************************************************************
751 * Helper Function to Trim and Format OS/2 Messages
752 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000753static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000754os2_formatmsg(char *msgbuf, int msglen, char *reason)
755{
756 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
757
758 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000759 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000760
Victor Stinner862490a2010-05-06 00:03:44 +0000761 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
762 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000763 }
764
765 /* Add Optional Reason Text */
766 if (reason) {
767 strcat(msgbuf, " : ");
768 strcat(msgbuf, reason);
769 }
770}
771
772/**********************************************************************
773 * Decode an OS/2 Operating System Error Code
774 *
775 * A convenience function to lookup an OS/2 error code and return a
776 * text message we can use to raise a Python exception.
777 *
778 * Notes:
779 * The messages for errors returned from the OS/2 kernel reside in
780 * the file OSO001.MSG in the \OS2 directory hierarchy.
781 *
782 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000783static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000784os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
785{
786 APIRET rc;
787 ULONG msglen;
788
789 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
790 Py_BEGIN_ALLOW_THREADS
791 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
792 errorcode, "oso001.msg", &msglen);
793 Py_END_ALLOW_THREADS
794
795 if (rc == NO_ERROR)
796 os2_formatmsg(msgbuf, msglen, reason);
797 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000798 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000799 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000800
801 return msgbuf;
802}
803
804/* Set an OS/2-specific error and return NULL. OS/2 kernel
805 errors are not in a global variable e.g. 'errno' nor are
806 they congruent with posix error numbers. */
807
Victor Stinnerd6f85422010-05-05 23:33:33 +0000808static PyObject *
809os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000810{
811 char text[1024];
812 PyObject *v;
813
814 os2_strerror(text, sizeof(text), code, "");
815
816 v = Py_BuildValue("(is)", code, text);
817 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000818 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000819 Py_DECREF(v);
820 }
821 return NULL; /* Signal to Python that an Exception is Pending */
822}
823
824#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825
826/* POSIX generic methods */
827
Barry Warsaw53699e91996-12-10 23:23:01 +0000828static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000829posix_fildes(PyObject *fdobj, int (*func)(int))
830{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000831 int fd;
832 int res;
833 fd = PyObject_AsFileDescriptor(fdobj);
834 if (fd < 0)
835 return NULL;
836 if (!_PyVerify_fd(fd))
837 return posix_error();
838 Py_BEGIN_ALLOW_THREADS
839 res = (*func)(fd);
840 Py_END_ALLOW_THREADS
841 if (res < 0)
842 return posix_error();
843 Py_INCREF(Py_None);
844 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000845}
Guido van Rossum21142a01999-01-08 21:05:37 +0000846
847static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000848posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000849{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000850 char *path1 = NULL;
851 int res;
852 if (!PyArg_ParseTuple(args, format,
853 Py_FileSystemDefaultEncoding, &path1))
854 return NULL;
855 Py_BEGIN_ALLOW_THREADS
856 res = (*func)(path1);
857 Py_END_ALLOW_THREADS
858 if (res < 0)
859 return posix_error_with_allocated_filename(path1);
860 PyMem_Free(path1);
861 Py_INCREF(Py_None);
862 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863}
864
Barry Warsaw53699e91996-12-10 23:23:01 +0000865static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000866posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000867 char *format,
868 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000870 char *path1 = NULL, *path2 = NULL;
871 int res;
872 if (!PyArg_ParseTuple(args, format,
873 Py_FileSystemDefaultEncoding, &path1,
874 Py_FileSystemDefaultEncoding, &path2))
875 return NULL;
876 Py_BEGIN_ALLOW_THREADS
877 res = (*func)(path1, path2);
878 Py_END_ALLOW_THREADS
879 PyMem_Free(path1);
880 PyMem_Free(path2);
881 if (res != 0)
882 /* XXX how to report both path1 and path2??? */
883 return posix_error();
884 Py_INCREF(Py_None);
885 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000886}
887
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000888#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000889static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000890win32_1str(PyObject* args, char* func,
891 char* format, BOOL (__stdcall *funcA)(LPCSTR),
892 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000893{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000894 PyObject *uni;
895 char *ansi;
896 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000897
Victor Stinnerd6f85422010-05-05 23:33:33 +0000898 if (!PyArg_ParseTuple(args, wformat, &uni))
899 PyErr_Clear();
900 else {
901 Py_BEGIN_ALLOW_THREADS
902 result = funcW(PyUnicode_AsUnicode(uni));
903 Py_END_ALLOW_THREADS
904 if (!result)
905 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
906 Py_INCREF(Py_None);
907 return Py_None;
908 }
909 if (!PyArg_ParseTuple(args, format, &ansi))
910 return NULL;
911 Py_BEGIN_ALLOW_THREADS
912 result = funcA(ansi);
913 Py_END_ALLOW_THREADS
914 if (!result)
915 return win32_error(func, ansi);
916 Py_INCREF(Py_None);
917 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000918
919}
920
921/* This is a reimplementation of the C library's chdir function,
922 but one that produces Win32 errors instead of DOS error codes.
923 chdir is essentially a wrapper around SetCurrentDirectory; however,
924 it also needs to set "magic" environment variables indicating
925 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000926static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000927win32_chdir(LPCSTR path)
928{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000929 char new_path[MAX_PATH+1];
930 int result;
931 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000932
Victor Stinnerd6f85422010-05-05 23:33:33 +0000933 if(!SetCurrentDirectoryA(path))
934 return FALSE;
935 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
936 if (!result)
937 return FALSE;
938 /* In the ANSI API, there should not be any paths longer
939 than MAX_PATH. */
940 assert(result <= MAX_PATH+1);
941 if (strncmp(new_path, "\\\\", 2) == 0 ||
942 strncmp(new_path, "//", 2) == 0)
943 /* UNC path, nothing to do. */
944 return TRUE;
945 env[1] = new_path[0];
946 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000947}
948
949/* The Unicode version differs from the ANSI version
950 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000951static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000952win32_wchdir(LPCWSTR path)
953{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000954 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
955 int result;
956 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000957
Victor Stinnerd6f85422010-05-05 23:33:33 +0000958 if(!SetCurrentDirectoryW(path))
959 return FALSE;
960 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
961 if (!result)
962 return FALSE;
963 if (result > MAX_PATH+1) {
964 new_path = malloc(result * sizeof(wchar_t));
965 if (!new_path) {
966 SetLastError(ERROR_OUTOFMEMORY);
967 return FALSE;
968 }
969 result = GetCurrentDirectoryW(result, new_path);
970 if (!result) {
971 free(new_path);
972 return FALSE;
973 }
974 }
975 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
976 wcsncmp(new_path, L"//", 2) == 0)
977 /* UNC path, nothing to do. */
978 return TRUE;
979 env[1] = new_path[0];
980 result = SetEnvironmentVariableW(env, new_path);
981 if (new_path != _new_path)
982 free(new_path);
983 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000984}
985#endif
986
Antoine Pitrouff48c0a2011-07-01 22:56:03 +0200987/* choose the appropriate stat and fstat functions and return structs */
988#undef STAT
989#undef FSTAT
990#undef STRUCT_STAT
991#if defined(MS_WIN64) || defined(MS_WINDOWS)
992# define STAT win32_stat
993# define FSTAT win32_fstat
994# define STRUCT_STAT struct win32_stat
995#else
996# define STAT stat
997# define FSTAT fstat
998# define STRUCT_STAT struct stat
999#endif
1000
Martin v. Löwis14694662006-02-03 12:54:16 +00001001#ifdef MS_WINDOWS
1002/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1003 - time stamps are restricted to second resolution
1004 - file modification times suffer from forth-and-back conversions between
1005 UTC and local time
1006 Therefore, we implement our own stat, based on the Win32 API directly.
1007*/
Victor Stinnerd6f85422010-05-05 23:33:33 +00001008#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001009
1010struct win32_stat{
1011 int st_dev;
1012 __int64 st_ino;
1013 unsigned short st_mode;
1014 int st_nlink;
1015 int st_uid;
1016 int st_gid;
1017 int st_rdev;
1018 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001019 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001020 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001021 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001022 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001023 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001024 int st_ctime_nsec;
1025};
1026
1027static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1028
1029static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001030FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001031{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001032 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1033 /* Cannot simply cast and dereference in_ptr,
1034 since it might not be aligned properly */
1035 __int64 in;
1036 memcpy(&in, in_ptr, sizeof(in));
1037 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001038 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001039}
1040
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001041static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001042time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001043{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001044 /* XXX endianness */
1045 __int64 out;
1046 out = time_in + secs_between_epochs;
1047 out = out * 10000000 + nsec_in / 100;
1048 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001049}
1050
Martin v. Löwis14694662006-02-03 12:54:16 +00001051/* Below, we *know* that ugo+r is 0444 */
1052#if _S_IREAD != 0400
1053#error Unsupported C library
1054#endif
1055static int
1056attributes_to_mode(DWORD attr)
1057{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001058 int m = 0;
1059 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1060 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1061 else
1062 m |= _S_IFREG;
1063 if (attr & FILE_ATTRIBUTE_READONLY)
1064 m |= 0444;
1065 else
1066 m |= 0666;
1067 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001068}
1069
1070static int
1071attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
1072{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001073 memset(result, 0, sizeof(*result));
1074 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1075 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1076 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1077 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1078 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001079
Victor Stinnerd6f85422010-05-05 23:33:33 +00001080 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001081}
1082
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001083static BOOL
1084attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1085{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001086 HANDLE hFindFile;
1087 WIN32_FIND_DATAA FileData;
1088 hFindFile = FindFirstFileA(pszFile, &FileData);
1089 if (hFindFile == INVALID_HANDLE_VALUE)
1090 return FALSE;
1091 FindClose(hFindFile);
1092 pfad->dwFileAttributes = FileData.dwFileAttributes;
1093 pfad->ftCreationTime = FileData.ftCreationTime;
1094 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1095 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1096 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1097 pfad->nFileSizeLow = FileData.nFileSizeLow;
1098 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001099}
1100
1101static BOOL
1102attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1103{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001104 HANDLE hFindFile;
1105 WIN32_FIND_DATAW FileData;
1106 hFindFile = FindFirstFileW(pszFile, &FileData);
1107 if (hFindFile == INVALID_HANDLE_VALUE)
1108 return FALSE;
1109 FindClose(hFindFile);
1110 pfad->dwFileAttributes = FileData.dwFileAttributes;
1111 pfad->ftCreationTime = FileData.ftCreationTime;
1112 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1113 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1114 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1115 pfad->nFileSizeLow = FileData.nFileSizeLow;
1116 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001117}
1118
Victor Stinnerd6f85422010-05-05 23:33:33 +00001119static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001120win32_stat(const char* path, struct win32_stat *result)
1121{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001122 WIN32_FILE_ATTRIBUTE_DATA info;
1123 int code;
1124 char *dot;
1125 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1126 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1127 /* Protocol violation: we explicitly clear errno, instead of
1128 setting it to a POSIX error. Callers should use GetLastError. */
1129 errno = 0;
1130 return -1;
1131 } else {
1132 /* Could not get attributes on open file. Fall back to
1133 reading the directory. */
1134 if (!attributes_from_dir(path, &info)) {
1135 /* Very strange. This should not fail now */
1136 errno = 0;
1137 return -1;
1138 }
1139 }
1140 }
1141 code = attribute_data_to_stat(&info, result);
1142 if (code != 0)
1143 return code;
1144 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1145 dot = strrchr(path, '.');
1146 if (dot) {
1147 if (stricmp(dot, ".bat") == 0 ||
1148 stricmp(dot, ".cmd") == 0 ||
1149 stricmp(dot, ".exe") == 0 ||
1150 stricmp(dot, ".com") == 0)
1151 result->st_mode |= 0111;
1152 }
1153 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001154}
1155
Victor Stinnerd6f85422010-05-05 23:33:33 +00001156static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001157win32_wstat(const wchar_t* path, struct win32_stat *result)
1158{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001159 int code;
1160 const wchar_t *dot;
1161 WIN32_FILE_ATTRIBUTE_DATA info;
1162 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1163 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1164 /* Protocol violation: we explicitly clear errno, instead of
1165 setting it to a POSIX error. Callers should use GetLastError. */
1166 errno = 0;
1167 return -1;
1168 } else {
1169 /* Could not get attributes on open file. Fall back to
1170 reading the directory. */
1171 if (!attributes_from_dir_w(path, &info)) {
1172 /* Very strange. This should not fail now */
1173 errno = 0;
1174 return -1;
1175 }
1176 }
1177 }
1178 code = attribute_data_to_stat(&info, result);
1179 if (code < 0)
1180 return code;
1181 /* Set IFEXEC if it is an .exe, .bat, ... */
1182 dot = wcsrchr(path, '.');
1183 if (dot) {
1184 if (_wcsicmp(dot, L".bat") == 0 ||
1185 _wcsicmp(dot, L".cmd") == 0 ||
1186 _wcsicmp(dot, L".exe") == 0 ||
1187 _wcsicmp(dot, L".com") == 0)
1188 result->st_mode |= 0111;
1189 }
1190 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001191}
1192
1193static int
1194win32_fstat(int file_number, struct win32_stat *result)
1195{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001196 BY_HANDLE_FILE_INFORMATION info;
1197 HANDLE h;
1198 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001199
Victor Stinnerd6f85422010-05-05 23:33:33 +00001200 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001201
Victor Stinnerd6f85422010-05-05 23:33:33 +00001202 /* Protocol violation: we explicitly clear errno, instead of
1203 setting it to a POSIX error. Callers should use GetLastError. */
1204 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001205
Victor Stinnerd6f85422010-05-05 23:33:33 +00001206 if (h == INVALID_HANDLE_VALUE) {
1207 /* This is really a C library error (invalid file handle).
1208 We set the Win32 error to the closes one matching. */
1209 SetLastError(ERROR_INVALID_HANDLE);
1210 return -1;
1211 }
1212 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001213
Victor Stinnerd6f85422010-05-05 23:33:33 +00001214 type = GetFileType(h);
1215 if (type == FILE_TYPE_UNKNOWN) {
1216 DWORD error = GetLastError();
1217 if (error != 0) {
1218 return -1;
1219 }
1220 /* else: valid but unknown file */
1221 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001222
Victor Stinnerd6f85422010-05-05 23:33:33 +00001223 if (type != FILE_TYPE_DISK) {
1224 if (type == FILE_TYPE_CHAR)
1225 result->st_mode = _S_IFCHR;
1226 else if (type == FILE_TYPE_PIPE)
1227 result->st_mode = _S_IFIFO;
1228 return 0;
1229 }
1230
1231 if (!GetFileInformationByHandle(h, &info)) {
1232 return -1;
1233 }
1234
1235 /* similar to stat() */
1236 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1237 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1238 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1239 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1240 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1241 /* specific to fstat() */
1242 result->st_nlink = info.nNumberOfLinks;
1243 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1244 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001245}
1246
1247#endif /* MS_WINDOWS */
1248
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001249PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001250"stat_result: Result from stat or lstat.\n\n\
1251This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001252 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001253or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1254\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001255Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1256or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001257\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001258See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001259
1260static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001261 {"st_mode", "protection bits"},
1262 {"st_ino", "inode"},
1263 {"st_dev", "device"},
1264 {"st_nlink", "number of hard links"},
1265 {"st_uid", "user ID of owner"},
1266 {"st_gid", "group ID of owner"},
1267 {"st_size", "total size, in bytes"},
1268 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1269 {NULL, "integer time of last access"},
1270 {NULL, "integer time of last modification"},
1271 {NULL, "integer time of last change"},
1272 {"st_atime", "time of last access"},
1273 {"st_mtime", "time of last modification"},
1274 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001275#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001276 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001277#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001278#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001279 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001280#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001281#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001282 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001283#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001284#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001285 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001286#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001287#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001288 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001289#endif
1290#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001291 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001292#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001293 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001294};
1295
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001296#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001297#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001298#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001299#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001300#endif
1301
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001302#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001303#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1304#else
1305#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1306#endif
1307
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001308#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001309#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1310#else
1311#define ST_RDEV_IDX ST_BLOCKS_IDX
1312#endif
1313
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001314#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1315#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1316#else
1317#define ST_FLAGS_IDX ST_RDEV_IDX
1318#endif
1319
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001320#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001321#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001322#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001323#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001324#endif
1325
1326#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1327#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1328#else
1329#define ST_BIRTHTIME_IDX ST_GEN_IDX
1330#endif
1331
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001333 "stat_result", /* name */
1334 stat_result__doc__, /* doc */
1335 stat_result_fields,
1336 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001337};
1338
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001339PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1341This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001342 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001343or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001345See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001346
1347static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001348 {"f_bsize", },
1349 {"f_frsize", },
1350 {"f_blocks", },
1351 {"f_bfree", },
1352 {"f_bavail", },
1353 {"f_files", },
1354 {"f_ffree", },
1355 {"f_favail", },
1356 {"f_flag", },
1357 {"f_namemax",},
1358 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001359};
1360
1361static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001362 "statvfs_result", /* name */
1363 statvfs_result__doc__, /* doc */
1364 statvfs_result_fields,
1365 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001366};
1367
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001368static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369static PyTypeObject StatResultType;
1370static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001371static newfunc structseq_new;
1372
1373static PyObject *
1374statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1375{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001376 PyStructSequence *result;
1377 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001378
Victor Stinnerd6f85422010-05-05 23:33:33 +00001379 result = (PyStructSequence*)structseq_new(type, args, kwds);
1380 if (!result)
1381 return NULL;
1382 /* If we have been initialized from a tuple,
1383 st_?time might be set to None. Initialize it
1384 from the int slots. */
1385 for (i = 7; i <= 9; i++) {
1386 if (result->ob_item[i+3] == Py_None) {
1387 Py_DECREF(Py_None);
1388 Py_INCREF(result->ob_item[i]);
1389 result->ob_item[i+3] = result->ob_item[i];
1390 }
1391 }
1392 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001393}
1394
1395
1396
1397/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001398static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001399
1400PyDoc_STRVAR(stat_float_times__doc__,
1401"stat_float_times([newval]) -> oldval\n\n\
1402Determine whether os.[lf]stat represents time stamps as float objects.\n\
1403If newval is True, future calls to stat() return floats, if it is False,\n\
1404future calls return ints. \n\
1405If newval is omitted, return the current setting.\n");
1406
1407static PyObject*
1408stat_float_times(PyObject* self, PyObject *args)
1409{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001410 int newval = -1;
1411 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1412 return NULL;
1413 if (newval == -1)
1414 /* Return old value */
1415 return PyBool_FromLong(_stat_float_times);
1416 _stat_float_times = newval;
1417 Py_INCREF(Py_None);
1418 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001419}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001420
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001421static void
1422fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1423{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001424 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001425#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001426 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001427#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001428 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001429#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001430 if (!ival)
1431 return;
1432 if (_stat_float_times) {
1433 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1434 } else {
1435 fval = ival;
1436 Py_INCREF(fval);
1437 }
1438 PyStructSequence_SET_ITEM(v, index, ival);
1439 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001440}
1441
Tim Peters5aa91602002-01-30 05:46:57 +00001442/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001443 (used by posix_stat() and posix_fstat()) */
1444static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001445_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001446{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001447 unsigned long ansec, mnsec, cnsec;
1448 PyObject *v = PyStructSequence_New(&StatResultType);
1449 if (v == NULL)
1450 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001451
Victor Stinnerd6f85422010-05-05 23:33:33 +00001452 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001453#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001454 PyStructSequence_SET_ITEM(v, 1,
1455 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001456#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001457 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001458#endif
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001459#ifdef MS_WINDOWS
1460 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001461#else
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001462 PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001463#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001464 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02001465#if defined(MS_WINDOWS)
1466 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
1467 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
1468#else
1469 PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
1470 PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
1471#endif
Fred Drake699f3522000-06-29 21:12:41 +00001472#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001473 PyStructSequence_SET_ITEM(v, 6,
1474 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001475#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001476 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001477#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001478
Martin v. Löwis14694662006-02-03 12:54:16 +00001479#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001480 ansec = st->st_atim.tv_nsec;
1481 mnsec = st->st_mtim.tv_nsec;
1482 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001483#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001484 ansec = st->st_atimespec.tv_nsec;
1485 mnsec = st->st_mtimespec.tv_nsec;
1486 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001487#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001488 ansec = st->st_atime_nsec;
1489 mnsec = st->st_mtime_nsec;
1490 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001491#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001492 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001493#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001494 fill_time(v, 7, st->st_atime, ansec);
1495 fill_time(v, 8, st->st_mtime, mnsec);
1496 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001497
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001498#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001499 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1500 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001501#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001502#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001503 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1504 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001505#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001506#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001507 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1508 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001509#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001510#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001511 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1512 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001513#endif
1514#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001515 {
1516 PyObject *val;
1517 unsigned long bsec,bnsec;
1518 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001519#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001520 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001521#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001522 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001523#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001524 if (_stat_float_times) {
1525 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1526 } else {
1527 val = PyInt_FromLong((long)bsec);
1528 }
1529 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1530 val);
1531 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001532#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001533#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001534 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1535 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001536#endif
Fred Drake699f3522000-06-29 21:12:41 +00001537
Victor Stinnerd6f85422010-05-05 23:33:33 +00001538 if (PyErr_Occurred()) {
1539 Py_DECREF(v);
1540 return NULL;
1541 }
Fred Drake699f3522000-06-29 21:12:41 +00001542
Victor Stinnerd6f85422010-05-05 23:33:33 +00001543 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001544}
1545
Martin v. Löwisd8948722004-06-02 09:57:56 +00001546#ifdef MS_WINDOWS
1547
1548/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1549 where / can be used in place of \ and the trailing slash is optional.
1550 Both SERVER and SHARE must have at least one character.
1551*/
1552
1553#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1554#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001555#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001556#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001557#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001558
Tim Peters4ad82172004-08-30 17:02:04 +00001559static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001560IsUNCRootA(char *path, int pathlen)
1561{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001562 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001563
Victor Stinnerd6f85422010-05-05 23:33:33 +00001564 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001565
Victor Stinnerd6f85422010-05-05 23:33:33 +00001566 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1567 /* minimum UNCRoot is \\x\y */
1568 return FALSE;
1569 for (i = 2; i < pathlen ; i++)
1570 if (ISSLASH(path[i])) break;
1571 if (i == 2 || i == pathlen)
1572 /* do not allow \\\SHARE or \\SERVER */
1573 return FALSE;
1574 share = i+1;
1575 for (i = share; i < pathlen; i++)
1576 if (ISSLASH(path[i])) break;
1577 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001578
Victor Stinnerd6f85422010-05-05 23:33:33 +00001579 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001580}
1581
Tim Peters4ad82172004-08-30 17:02:04 +00001582static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001583IsUNCRootW(Py_UNICODE *path, int pathlen)
1584{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001585 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001586
Victor Stinnerd6f85422010-05-05 23:33:33 +00001587 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001588
Victor Stinnerd6f85422010-05-05 23:33:33 +00001589 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1590 /* minimum UNCRoot is \\x\y */
1591 return FALSE;
1592 for (i = 2; i < pathlen ; i++)
1593 if (ISSLASH(path[i])) break;
1594 if (i == 2 || i == pathlen)
1595 /* do not allow \\\SHARE or \\SERVER */
1596 return FALSE;
1597 share = i+1;
1598 for (i = share; i < pathlen; i++)
1599 if (ISSLASH(path[i])) break;
1600 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001601
Victor Stinnerd6f85422010-05-05 23:33:33 +00001602 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001603}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001604#endif /* MS_WINDOWS */
1605
Barry Warsaw53699e91996-12-10 23:23:01 +00001606static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001607posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001608 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001609#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001610 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001611#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001612 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001613#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001614 char *wformat,
1615 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001616{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001617 STRUCT_STAT st;
1618 char *path = NULL; /* pass this to stat; do not free() it */
1619 char *pathfree = NULL; /* this memory must be free'd */
1620 int res;
1621 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001622
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001623#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001624 PyUnicodeObject *po;
1625 if (PyArg_ParseTuple(args, wformat, &po)) {
1626 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001627
Victor Stinnerd6f85422010-05-05 23:33:33 +00001628 Py_BEGIN_ALLOW_THREADS
1629 /* PyUnicode_AS_UNICODE result OK without
1630 thread lock as it is a simple dereference. */
1631 res = wstatfunc(wpath, &st);
1632 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001633
Victor Stinnerd6f85422010-05-05 23:33:33 +00001634 if (res != 0)
1635 return win32_error_unicode("stat", wpath);
1636 return _pystat_fromstructstat(&st);
1637 }
1638 /* Drop the argument parsing error as narrow strings
1639 are also valid. */
1640 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001641#endif
1642
Victor Stinnerd6f85422010-05-05 23:33:33 +00001643 if (!PyArg_ParseTuple(args, format,
1644 Py_FileSystemDefaultEncoding, &path))
1645 return NULL;
1646 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001647
Victor Stinnerd6f85422010-05-05 23:33:33 +00001648 Py_BEGIN_ALLOW_THREADS
1649 res = (*statfunc)(path, &st);
1650 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001651
Victor Stinnerd6f85422010-05-05 23:33:33 +00001652 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001653#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001654 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001655#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001656 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001657#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001658 }
1659 else
1660 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001661
Victor Stinnerd6f85422010-05-05 23:33:33 +00001662 PyMem_Free(pathfree);
1663 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001664}
1665
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001666/* POSIX methods */
1667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001668PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001669"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001670Use the real uid/gid to test for access to a path. Note that most\n\
1671operations will use the effective uid/gid, therefore this routine can\n\
1672be used in a suid/sgid environment to test if the invoking user has the\n\
1673specified access to the path. The mode argument can be F_OK to test\n\
1674existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001675
1676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001677posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001678{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001679 char *path;
1680 int mode;
1681
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001682#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001683 DWORD attr;
1684 PyUnicodeObject *po;
1685 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1686 Py_BEGIN_ALLOW_THREADS
1687 /* PyUnicode_AS_UNICODE OK without thread lock as
1688 it is a simple dereference. */
1689 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1690 Py_END_ALLOW_THREADS
1691 goto finish;
1692 }
1693 /* Drop the argument parsing error as narrow strings
1694 are also valid. */
1695 PyErr_Clear();
1696 if (!PyArg_ParseTuple(args, "eti:access",
1697 Py_FileSystemDefaultEncoding, &path, &mode))
1698 return NULL;
1699 Py_BEGIN_ALLOW_THREADS
1700 attr = GetFileAttributesA(path);
1701 Py_END_ALLOW_THREADS
1702 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001703finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001704 if (attr == 0xFFFFFFFF)
1705 /* File does not exist, or cannot read attributes */
1706 return PyBool_FromLong(0);
1707 /* Access is possible if either write access wasn't requested, or
1708 the file isn't read-only, or if it's a directory, as there are
1709 no read-only directories on Windows. */
1710 return PyBool_FromLong(!(mode & 2)
1711 || !(attr & FILE_ATTRIBUTE_READONLY)
1712 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001713#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001714 int res;
1715 if (!PyArg_ParseTuple(args, "eti:access",
1716 Py_FileSystemDefaultEncoding, &path, &mode))
1717 return NULL;
1718 Py_BEGIN_ALLOW_THREADS
1719 res = access(path, mode);
1720 Py_END_ALLOW_THREADS
1721 PyMem_Free(path);
1722 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001723#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001724}
1725
Guido van Rossumd371ff11999-01-25 16:12:23 +00001726#ifndef F_OK
1727#define F_OK 0
1728#endif
1729#ifndef R_OK
1730#define R_OK 4
1731#endif
1732#ifndef W_OK
1733#define W_OK 2
1734#endif
1735#ifndef X_OK
1736#define X_OK 1
1737#endif
1738
1739#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001740PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001741"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001742Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001743
1744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001745posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001746{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001747 int id;
1748 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749
Victor Stinnerd6f85422010-05-05 23:33:33 +00001750 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1751 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001752
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001753#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001754 /* file descriptor 0 only, the default input device (stdin) */
1755 if (id == 0) {
1756 ret = ttyname();
1757 }
1758 else {
1759 ret = NULL;
1760 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001761#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001762 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001763#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001764 if (ret == NULL)
1765 return posix_error();
1766 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001767}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001768#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001770#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001771PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001772"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001774
1775static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001776posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001777{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001778 char *ret;
1779 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001780
Greg Wardb48bc172000-03-01 21:51:56 +00001781#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001782 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001783#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001784 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001785#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001786 if (ret == NULL)
1787 return posix_error();
1788 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001789}
1790#endif
1791
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001793"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001794Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001795
Barry Warsaw53699e91996-12-10 23:23:01 +00001796static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001797posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001798{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001799#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001800 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001801#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001802 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001803#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001804 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001805#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001806 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001807#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001808}
1809
Fred Drake4d1e64b2002-04-15 19:40:07 +00001810#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001812"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001813Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001814opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001815
1816static PyObject *
1817posix_fchdir(PyObject *self, PyObject *fdobj)
1818{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001819 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001820}
1821#endif /* HAVE_FCHDIR */
1822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001824PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001825"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001827
Barry Warsaw53699e91996-12-10 23:23:01 +00001828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001829posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001831 char *path = NULL;
1832 int i;
1833 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001834#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001835 DWORD attr;
1836 PyUnicodeObject *po;
1837 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1838 Py_BEGIN_ALLOW_THREADS
1839 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1840 if (attr != 0xFFFFFFFF) {
1841 if (i & _S_IWRITE)
1842 attr &= ~FILE_ATTRIBUTE_READONLY;
1843 else
1844 attr |= FILE_ATTRIBUTE_READONLY;
1845 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1846 }
1847 else
1848 res = 0;
1849 Py_END_ALLOW_THREADS
1850 if (!res)
1851 return win32_error_unicode("chmod",
1852 PyUnicode_AS_UNICODE(po));
1853 Py_INCREF(Py_None);
1854 return Py_None;
1855 }
1856 /* Drop the argument parsing error as narrow strings
1857 are also valid. */
1858 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001859
Victor Stinnerd6f85422010-05-05 23:33:33 +00001860 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1861 &path, &i))
1862 return NULL;
1863 Py_BEGIN_ALLOW_THREADS
1864 attr = GetFileAttributesA(path);
1865 if (attr != 0xFFFFFFFF) {
1866 if (i & _S_IWRITE)
1867 attr &= ~FILE_ATTRIBUTE_READONLY;
1868 else
1869 attr |= FILE_ATTRIBUTE_READONLY;
1870 res = SetFileAttributesA(path, attr);
1871 }
1872 else
1873 res = 0;
1874 Py_END_ALLOW_THREADS
1875 if (!res) {
1876 win32_error("chmod", path);
1877 PyMem_Free(path);
1878 return NULL;
1879 }
1880 PyMem_Free(path);
1881 Py_INCREF(Py_None);
1882 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001883#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001884 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1885 &path, &i))
1886 return NULL;
1887 Py_BEGIN_ALLOW_THREADS
1888 res = chmod(path, i);
1889 Py_END_ALLOW_THREADS
1890 if (res < 0)
1891 return posix_error_with_allocated_filename(path);
1892 PyMem_Free(path);
1893 Py_INCREF(Py_None);
1894 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001895#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001896}
1897
Christian Heimes36281872007-11-30 21:11:28 +00001898#ifdef HAVE_FCHMOD
1899PyDoc_STRVAR(posix_fchmod__doc__,
1900"fchmod(fd, mode)\n\n\
1901Change the access permissions of the file given by file\n\
1902descriptor fd.");
1903
1904static PyObject *
1905posix_fchmod(PyObject *self, PyObject *args)
1906{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001907 int fd, mode, res;
1908 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1909 return NULL;
1910 Py_BEGIN_ALLOW_THREADS
1911 res = fchmod(fd, mode);
1912 Py_END_ALLOW_THREADS
1913 if (res < 0)
1914 return posix_error();
1915 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001916}
1917#endif /* HAVE_FCHMOD */
1918
1919#ifdef HAVE_LCHMOD
1920PyDoc_STRVAR(posix_lchmod__doc__,
1921"lchmod(path, mode)\n\n\
1922Change the access permissions of a file. If path is a symlink, this\n\
1923affects the link itself rather than the target.");
1924
1925static PyObject *
1926posix_lchmod(PyObject *self, PyObject *args)
1927{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001928 char *path = NULL;
1929 int i;
1930 int res;
1931 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1932 &path, &i))
1933 return NULL;
1934 Py_BEGIN_ALLOW_THREADS
1935 res = lchmod(path, i);
1936 Py_END_ALLOW_THREADS
1937 if (res < 0)
1938 return posix_error_with_allocated_filename(path);
1939 PyMem_Free(path);
1940 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001941}
1942#endif /* HAVE_LCHMOD */
1943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001944
Martin v. Löwis382abef2007-02-19 10:55:19 +00001945#ifdef HAVE_CHFLAGS
1946PyDoc_STRVAR(posix_chflags__doc__,
1947"chflags(path, flags)\n\n\
1948Set file flags.");
1949
1950static PyObject *
1951posix_chflags(PyObject *self, PyObject *args)
1952{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001953 char *path;
1954 unsigned long flags;
1955 int res;
1956 if (!PyArg_ParseTuple(args, "etk:chflags",
1957 Py_FileSystemDefaultEncoding, &path, &flags))
1958 return NULL;
1959 Py_BEGIN_ALLOW_THREADS
1960 res = chflags(path, flags);
1961 Py_END_ALLOW_THREADS
1962 if (res < 0)
1963 return posix_error_with_allocated_filename(path);
1964 PyMem_Free(path);
1965 Py_INCREF(Py_None);
1966 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001967}
1968#endif /* HAVE_CHFLAGS */
1969
1970#ifdef HAVE_LCHFLAGS
1971PyDoc_STRVAR(posix_lchflags__doc__,
1972"lchflags(path, flags)\n\n\
1973Set file flags.\n\
1974This function will not follow symbolic links.");
1975
1976static PyObject *
1977posix_lchflags(PyObject *self, PyObject *args)
1978{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001979 char *path;
1980 unsigned long flags;
1981 int res;
1982 if (!PyArg_ParseTuple(args, "etk:lchflags",
1983 Py_FileSystemDefaultEncoding, &path, &flags))
1984 return NULL;
1985 Py_BEGIN_ALLOW_THREADS
1986 res = lchflags(path, flags);
1987 Py_END_ALLOW_THREADS
1988 if (res < 0)
1989 return posix_error_with_allocated_filename(path);
1990 PyMem_Free(path);
1991 Py_INCREF(Py_None);
1992 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001993}
1994#endif /* HAVE_LCHFLAGS */
1995
Martin v. Löwis244edc82001-10-04 22:44:26 +00001996#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001998"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001999Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002000
2001static PyObject *
2002posix_chroot(PyObject *self, PyObject *args)
2003{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002004 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002005}
2006#endif
2007
Guido van Rossum21142a01999-01-08 21:05:37 +00002008#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002009PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002010"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002012
2013static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002014posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002015{
Stefan Krah93f7a322010-11-26 17:35:50 +00002016 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002017}
2018#endif /* HAVE_FSYNC */
2019
2020#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002021
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002022#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002023extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2024#endif
2025
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002027"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002028force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002030
2031static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002032posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002033{
Stefan Krah93f7a322010-11-26 17:35:50 +00002034 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002035}
2036#endif /* HAVE_FDATASYNC */
2037
2038
Fredrik Lundh10723342000-07-10 16:38:09 +00002039#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002040PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002041"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002042Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002043
Barry Warsaw53699e91996-12-10 23:23:01 +00002044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002045posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002046{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002047 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002048 uid_t uid;
2049 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002050 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002051 if (!PyArg_ParseTuple(args, "etO&O&:chown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002052 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002053 _Py_Uid_Converter, &uid,
2054 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002055 return NULL;
2056 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002057 res = chown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002058 Py_END_ALLOW_THREADS
2059 if (res < 0)
2060 return posix_error_with_allocated_filename(path);
2061 PyMem_Free(path);
2062 Py_INCREF(Py_None);
2063 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002064}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002065#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002066
Christian Heimes36281872007-11-30 21:11:28 +00002067#ifdef HAVE_FCHOWN
2068PyDoc_STRVAR(posix_fchown__doc__,
2069"fchown(fd, uid, gid)\n\n\
2070Change the owner and group id of the file given by file descriptor\n\
2071fd to the numeric uid and gid.");
2072
2073static PyObject *
2074posix_fchown(PyObject *self, PyObject *args)
2075{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002076 int fd;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002077 uid_t uid;
2078 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002079 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002080 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
2081 _Py_Uid_Converter, &uid,
2082 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002083 return NULL;
2084 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002085 res = fchown(fd, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002086 Py_END_ALLOW_THREADS
2087 if (res < 0)
2088 return posix_error();
2089 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00002090}
2091#endif /* HAVE_FCHOWN */
2092
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002093#ifdef HAVE_LCHOWN
2094PyDoc_STRVAR(posix_lchown__doc__,
2095"lchown(path, uid, gid)\n\n\
2096Change the owner and group id of path to the numeric uid and gid.\n\
2097This function will not follow symbolic links.");
2098
2099static PyObject *
2100posix_lchown(PyObject *self, PyObject *args)
2101{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002102 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002103 uid_t uid;
2104 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002105 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002106 if (!PyArg_ParseTuple(args, "etO&O&:lchown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002107 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002108 _Py_Uid_Converter, &uid,
2109 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002110 return NULL;
2111 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002112 res = lchown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002113 Py_END_ALLOW_THREADS
2114 if (res < 0)
2115 return posix_error_with_allocated_filename(path);
2116 PyMem_Free(path);
2117 Py_INCREF(Py_None);
2118 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002119}
2120#endif /* HAVE_LCHOWN */
2121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Guido van Rossum36bc6801995-06-14 22:54:23 +00002123#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002124PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002125"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002126Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002127
Trent Nelsonda4277a2012-08-29 09:20:41 -04002128#if (defined(__sun) && defined(__SVR4)) || \
2129 defined(__OpenBSD__) || \
2130 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00002131/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
2132static PyObject *
2133posix_getcwd(PyObject *self, PyObject *noargs)
2134{
2135 char buf[PATH_MAX+2];
2136 char *res;
2137
2138 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00002139 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00002140 Py_END_ALLOW_THREADS
2141
2142 if (res == NULL)
2143 return posix_error();
2144
2145 return PyString_FromString(buf);
2146}
2147#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002149posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002150{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002151 int bufsize_incr = 1024;
2152 int bufsize = 0;
2153 char *tmpbuf = NULL;
2154 char *res = NULL;
2155 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002156
Victor Stinnerd6f85422010-05-05 23:33:33 +00002157 Py_BEGIN_ALLOW_THREADS
2158 do {
2159 bufsize = bufsize + bufsize_incr;
2160 tmpbuf = malloc(bufsize);
2161 if (tmpbuf == NULL) {
2162 break;
2163 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002164#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002165 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002166#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002167 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002168#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002169
Victor Stinnerd6f85422010-05-05 23:33:33 +00002170 if (res == NULL) {
2171 free(tmpbuf);
2172 }
2173 } while ((res == NULL) && (errno == ERANGE));
2174 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002175
Victor Stinnerd6f85422010-05-05 23:33:33 +00002176 if (res == NULL)
2177 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002178
Victor Stinnerd6f85422010-05-05 23:33:33 +00002179 dynamic_return = PyString_FromString(tmpbuf);
2180 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002181
Victor Stinnerd6f85422010-05-05 23:33:33 +00002182 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002183}
Stefan Krah182ae642010-07-13 19:17:08 +00002184#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002185
Walter Dörwald3b918c32002-11-21 20:18:46 +00002186#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187PyDoc_STRVAR(posix_getcwdu__doc__,
2188"getcwdu() -> path\n\n\
2189Return a unicode string representing the current working directory.");
2190
2191static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002192posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002193{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002194 char buf[1026];
2195 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002196
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002197#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002198 DWORD len;
2199 wchar_t wbuf[1026];
2200 wchar_t *wbuf2 = wbuf;
2201 PyObject *resobj;
2202 Py_BEGIN_ALLOW_THREADS
2203 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2204 /* If the buffer is large enough, len does not include the
2205 terminating \0. If the buffer is too small, len includes
2206 the space needed for the terminator. */
2207 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2208 wbuf2 = malloc(len * sizeof(wchar_t));
2209 if (wbuf2)
2210 len = GetCurrentDirectoryW(len, wbuf2);
2211 }
2212 Py_END_ALLOW_THREADS
2213 if (!wbuf2) {
2214 PyErr_NoMemory();
2215 return NULL;
2216 }
2217 if (!len) {
2218 if (wbuf2 != wbuf) free(wbuf2);
2219 return win32_error("getcwdu", NULL);
2220 }
2221 resobj = PyUnicode_FromWideChar(wbuf2, len);
2222 if (wbuf2 != wbuf) free(wbuf2);
2223 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002224#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002225
Victor Stinnerd6f85422010-05-05 23:33:33 +00002226 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002227#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002228 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002229#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002230 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002231#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002232 Py_END_ALLOW_THREADS
2233 if (res == NULL)
2234 return posix_error();
2235 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002236}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002237#endif /* Py_USING_UNICODE */
2238#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002239
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002240
Guido van Rossumb6775db1994-08-01 11:34:53 +00002241#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002242PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002243"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002244Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002245
Barry Warsaw53699e91996-12-10 23:23:01 +00002246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002247posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002248{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002249 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002250}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002251#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002254PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002255"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002256Return a list containing the names of the entries in the directory.\n\
2257\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002258 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002259\n\
2260The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002261entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002262
Barry Warsaw53699e91996-12-10 23:23:01 +00002263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002264posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002265{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002266 /* XXX Should redo this putting the (now four) versions of opendir
2267 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002268#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002269
Victor Stinnerd6f85422010-05-05 23:33:33 +00002270 PyObject *d, *v;
2271 HANDLE hFindFile;
2272 BOOL result;
2273 WIN32_FIND_DATA FileData;
2274 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2275 char *bufptr = namebuf;
2276 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002277
Victor Stinnerd6f85422010-05-05 23:33:33 +00002278 PyObject *po;
2279 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2280 WIN32_FIND_DATAW wFileData;
2281 Py_UNICODE *wnamebuf;
2282 /* Overallocate for \\*.*\0 */
2283 len = PyUnicode_GET_SIZE(po);
2284 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2285 if (!wnamebuf) {
2286 PyErr_NoMemory();
2287 return NULL;
2288 }
2289 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2290 if (len > 0) {
2291 Py_UNICODE wch = wnamebuf[len-1];
2292 if (wch != L'/' && wch != L'\\' && wch != L':')
2293 wnamebuf[len++] = L'\\';
2294 wcscpy(wnamebuf + len, L"*.*");
2295 }
2296 if ((d = PyList_New(0)) == NULL) {
2297 free(wnamebuf);
2298 return NULL;
2299 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002300 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002301 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002302 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002303 if (hFindFile == INVALID_HANDLE_VALUE) {
2304 int error = GetLastError();
2305 if (error == ERROR_FILE_NOT_FOUND) {
2306 free(wnamebuf);
2307 return d;
2308 }
2309 Py_DECREF(d);
2310 win32_error_unicode("FindFirstFileW", wnamebuf);
2311 free(wnamebuf);
2312 return NULL;
2313 }
2314 do {
2315 /* Skip over . and .. */
2316 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2317 wcscmp(wFileData.cFileName, L"..") != 0) {
2318 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2319 if (v == NULL) {
2320 Py_DECREF(d);
2321 d = NULL;
2322 break;
2323 }
2324 if (PyList_Append(d, v) != 0) {
2325 Py_DECREF(v);
2326 Py_DECREF(d);
2327 d = NULL;
2328 break;
2329 }
2330 Py_DECREF(v);
2331 }
2332 Py_BEGIN_ALLOW_THREADS
2333 result = FindNextFileW(hFindFile, &wFileData);
2334 Py_END_ALLOW_THREADS
2335 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2336 it got to the end of the directory. */
2337 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2338 Py_DECREF(d);
2339 win32_error_unicode("FindNextFileW", wnamebuf);
2340 FindClose(hFindFile);
2341 free(wnamebuf);
2342 return NULL;
2343 }
2344 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002345
Victor Stinnerd6f85422010-05-05 23:33:33 +00002346 if (FindClose(hFindFile) == FALSE) {
2347 Py_DECREF(d);
2348 win32_error_unicode("FindClose", wnamebuf);
2349 free(wnamebuf);
2350 return NULL;
2351 }
2352 free(wnamebuf);
2353 return d;
2354 }
2355 /* Drop the argument parsing error as narrow strings
2356 are also valid. */
2357 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002358
Victor Stinnerd6f85422010-05-05 23:33:33 +00002359 if (!PyArg_ParseTuple(args, "et#:listdir",
2360 Py_FileSystemDefaultEncoding, &bufptr, &len))
2361 return NULL;
2362 if (len > 0) {
2363 char ch = namebuf[len-1];
2364 if (ch != SEP && ch != ALTSEP && ch != ':')
2365 namebuf[len++] = '/';
2366 strcpy(namebuf + len, "*.*");
2367 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002368
Victor Stinnerd6f85422010-05-05 23:33:33 +00002369 if ((d = PyList_New(0)) == NULL)
2370 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002371
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002372 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002373 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002374 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002375 if (hFindFile == INVALID_HANDLE_VALUE) {
2376 int error = GetLastError();
2377 if (error == ERROR_FILE_NOT_FOUND)
2378 return d;
2379 Py_DECREF(d);
2380 return win32_error("FindFirstFile", namebuf);
2381 }
2382 do {
2383 /* Skip over . and .. */
2384 if (strcmp(FileData.cFileName, ".") != 0 &&
2385 strcmp(FileData.cFileName, "..") != 0) {
2386 v = PyString_FromString(FileData.cFileName);
2387 if (v == NULL) {
2388 Py_DECREF(d);
2389 d = NULL;
2390 break;
2391 }
2392 if (PyList_Append(d, v) != 0) {
2393 Py_DECREF(v);
2394 Py_DECREF(d);
2395 d = NULL;
2396 break;
2397 }
2398 Py_DECREF(v);
2399 }
2400 Py_BEGIN_ALLOW_THREADS
2401 result = FindNextFile(hFindFile, &FileData);
2402 Py_END_ALLOW_THREADS
2403 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2404 it got to the end of the directory. */
2405 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2406 Py_DECREF(d);
2407 win32_error("FindNextFile", namebuf);
2408 FindClose(hFindFile);
2409 return NULL;
2410 }
2411 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002412
Victor Stinnerd6f85422010-05-05 23:33:33 +00002413 if (FindClose(hFindFile) == FALSE) {
2414 Py_DECREF(d);
2415 return win32_error("FindClose", namebuf);
2416 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002417
Victor Stinnerd6f85422010-05-05 23:33:33 +00002418 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002419
Tim Peters0bb44a42000-09-15 07:44:49 +00002420#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002421
2422#ifndef MAX_PATH
2423#define MAX_PATH CCHMAXPATH
2424#endif
2425 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002426 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002427 PyObject *d, *v;
2428 char namebuf[MAX_PATH+5];
2429 HDIR hdir = 1;
2430 ULONG srchcnt = 1;
2431 FILEFINDBUF3 ep;
2432 APIRET rc;
2433
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002434 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 return NULL;
2436 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002437 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438 return NULL;
2439 }
2440 strcpy(namebuf, name);
2441 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002442 if (*pt == ALTSEP)
2443 *pt = SEP;
2444 if (namebuf[len-1] != SEP)
2445 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002446 strcpy(namebuf + len, "*.*");
2447
Victor Stinnerd6f85422010-05-05 23:33:33 +00002448 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002449 return NULL;
2450
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002451 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2452 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002454 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2455 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2456 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002457
2458 if (rc != NO_ERROR) {
2459 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002460 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002461 }
2462
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002463 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 do {
2465 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002466 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002467 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002468
2469 strcpy(namebuf, ep.achName);
2470
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002471 /* Leave Case of Name Alone -- In Native Form */
2472 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002473
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002474 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475 if (v == NULL) {
2476 Py_DECREF(d);
2477 d = NULL;
2478 break;
2479 }
2480 if (PyList_Append(d, v) != 0) {
2481 Py_DECREF(v);
2482 Py_DECREF(d);
2483 d = NULL;
2484 break;
2485 }
2486 Py_DECREF(v);
2487 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2488 }
2489
2490 return d;
2491#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002492
Victor Stinnerd6f85422010-05-05 23:33:33 +00002493 char *name = NULL;
2494 PyObject *d, *v;
2495 DIR *dirp;
2496 struct dirent *ep;
2497 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002498
Victor Stinnerd6f85422010-05-05 23:33:33 +00002499 errno = 0;
2500 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2501 arg_is_unicode = 0;
2502 PyErr_Clear();
2503 }
2504 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2505 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002506 Py_BEGIN_ALLOW_THREADS
2507 dirp = opendir(name);
2508 Py_END_ALLOW_THREADS
2509 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002510 return posix_error_with_allocated_filename(name);
2511 }
2512 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002513 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002514 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002515 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002516 PyMem_Free(name);
2517 return NULL;
2518 }
2519 for (;;) {
2520 errno = 0;
2521 Py_BEGIN_ALLOW_THREADS
2522 ep = readdir(dirp);
2523 Py_END_ALLOW_THREADS
2524 if (ep == NULL) {
2525 if (errno == 0) {
2526 break;
2527 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002528 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002529 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002530 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002531 Py_DECREF(d);
2532 return posix_error_with_allocated_filename(name);
2533 }
2534 }
2535 if (ep->d_name[0] == '.' &&
2536 (NAMLEN(ep) == 1 ||
2537 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2538 continue;
2539 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2540 if (v == NULL) {
2541 Py_DECREF(d);
2542 d = NULL;
2543 break;
2544 }
Just van Rossum46c97842003-02-25 21:42:15 +00002545#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002546 if (arg_is_unicode) {
2547 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002548
Victor Stinnerd6f85422010-05-05 23:33:33 +00002549 w = PyUnicode_FromEncodedObject(v,
2550 Py_FileSystemDefaultEncoding,
2551 "strict");
2552 if (w != NULL) {
2553 Py_DECREF(v);
2554 v = w;
2555 }
2556 else {
2557 /* fall back to the original byte string, as
2558 discussed in patch #683592 */
2559 PyErr_Clear();
2560 }
2561 }
Just van Rossum46c97842003-02-25 21:42:15 +00002562#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002563 if (PyList_Append(d, v) != 0) {
2564 Py_DECREF(v);
2565 Py_DECREF(d);
2566 d = NULL;
2567 break;
2568 }
2569 Py_DECREF(v);
2570 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002571 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002572 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002573 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002574 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002575
Victor Stinnerd6f85422010-05-05 23:33:33 +00002576 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002577
Tim Peters0bb44a42000-09-15 07:44:49 +00002578#endif /* which OS */
2579} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002580
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002581#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002582/* A helper function for abspath on win32 */
2583static PyObject *
2584posix__getfullpathname(PyObject *self, PyObject *args)
2585{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002586 /* assume encoded strings won't more than double no of chars */
2587 char inbuf[MAX_PATH*2];
2588 char *inbufp = inbuf;
2589 Py_ssize_t insize = sizeof(inbuf);
2590 char outbuf[MAX_PATH*2];
2591 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002592
Victor Stinnerd6f85422010-05-05 23:33:33 +00002593 PyUnicodeObject *po;
2594 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2595 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2596 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2597 Py_UNICODE *wtemp;
2598 DWORD result;
2599 PyObject *v;
2600 result = GetFullPathNameW(wpath,
2601 sizeof(woutbuf)/sizeof(woutbuf[0]),
2602 woutbuf, &wtemp);
2603 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2604 woutbufp = malloc(result * sizeof(Py_UNICODE));
2605 if (!woutbufp)
2606 return PyErr_NoMemory();
2607 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2608 }
2609 if (result)
2610 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2611 else
2612 v = win32_error_unicode("GetFullPathNameW", wpath);
2613 if (woutbufp != woutbuf)
2614 free(woutbufp);
2615 return v;
2616 }
2617 /* Drop the argument parsing error as narrow strings
2618 are also valid. */
2619 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002620
Victor Stinnerd6f85422010-05-05 23:33:33 +00002621 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2622 Py_FileSystemDefaultEncoding, &inbufp,
2623 &insize))
2624 return NULL;
2625 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2626 outbuf, &temp))
2627 return win32_error("GetFullPathName", inbuf);
2628 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2629 return PyUnicode_Decode(outbuf, strlen(outbuf),
2630 Py_FileSystemDefaultEncoding, NULL);
2631 }
2632 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002633} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002634#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002637"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002638Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002639
Barry Warsaw53699e91996-12-10 23:23:01 +00002640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002641posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002642{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002643 int res;
2644 char *path = NULL;
2645 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002646
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002647#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002648 PyUnicodeObject *po;
2649 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2650 Py_BEGIN_ALLOW_THREADS
2651 /* PyUnicode_AS_UNICODE OK without thread lock as
2652 it is a simple dereference. */
2653 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2654 Py_END_ALLOW_THREADS
2655 if (!res)
2656 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2657 Py_INCREF(Py_None);
2658 return Py_None;
2659 }
2660 /* Drop the argument parsing error as narrow strings
2661 are also valid. */
2662 PyErr_Clear();
2663 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2664 Py_FileSystemDefaultEncoding, &path, &mode))
2665 return NULL;
2666 Py_BEGIN_ALLOW_THREADS
2667 /* PyUnicode_AS_UNICODE OK without thread lock as
2668 it is a simple dereference. */
2669 res = CreateDirectoryA(path, NULL);
2670 Py_END_ALLOW_THREADS
2671 if (!res) {
2672 win32_error("mkdir", path);
2673 PyMem_Free(path);
2674 return NULL;
2675 }
2676 PyMem_Free(path);
2677 Py_INCREF(Py_None);
2678 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002679#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002680
Victor Stinnerd6f85422010-05-05 23:33:33 +00002681 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2682 Py_FileSystemDefaultEncoding, &path, &mode))
2683 return NULL;
2684 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002685#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002686 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002687#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002688 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002689#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002690 Py_END_ALLOW_THREADS
2691 if (res < 0)
2692 return posix_error_with_allocated_filename(path);
2693 PyMem_Free(path);
2694 Py_INCREF(Py_None);
2695 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002696#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002697}
2698
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002699
Neal Norwitz1818ed72006-03-26 00:29:48 +00002700/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2701#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002702#include <sys/resource.h>
2703#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002704
Neal Norwitz1818ed72006-03-26 00:29:48 +00002705
2706#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002707PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002708"nice(inc) -> new_priority\n\n\
2709Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002710
Barry Warsaw53699e91996-12-10 23:23:01 +00002711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002712posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002713{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002714 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002715
Victor Stinnerd6f85422010-05-05 23:33:33 +00002716 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2717 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002718
Victor Stinnerd6f85422010-05-05 23:33:33 +00002719 /* There are two flavours of 'nice': one that returns the new
2720 priority (as required by almost all standards out there) and the
2721 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2722 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002723
Victor Stinnerd6f85422010-05-05 23:33:33 +00002724 If we are of the nice family that returns the new priority, we
2725 need to clear errno before the call, and check if errno is filled
2726 before calling posix_error() on a returnvalue of -1, because the
2727 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002728
Victor Stinnerd6f85422010-05-05 23:33:33 +00002729 errno = 0;
2730 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002731#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002732 if (value == 0)
2733 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002734#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002735 if (value == -1 && errno != 0)
2736 /* either nice() or getpriority() returned an error */
2737 return posix_error();
2738 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002739}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002740#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002741
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002742PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002743"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002744Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002745
Barry Warsaw53699e91996-12-10 23:23:01 +00002746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002747posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002748{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002749#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002750 PyObject *o1, *o2;
2751 char *p1, *p2;
2752 BOOL result;
2753 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2754 goto error;
2755 if (!convert_to_unicode(&o1))
2756 goto error;
2757 if (!convert_to_unicode(&o2)) {
2758 Py_DECREF(o1);
2759 goto error;
2760 }
2761 Py_BEGIN_ALLOW_THREADS
2762 result = MoveFileW(PyUnicode_AsUnicode(o1),
2763 PyUnicode_AsUnicode(o2));
2764 Py_END_ALLOW_THREADS
2765 Py_DECREF(o1);
2766 Py_DECREF(o2);
2767 if (!result)
2768 return win32_error("rename", NULL);
2769 Py_INCREF(Py_None);
2770 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002771error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002772 PyErr_Clear();
2773 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2774 return NULL;
2775 Py_BEGIN_ALLOW_THREADS
2776 result = MoveFileA(p1, p2);
2777 Py_END_ALLOW_THREADS
2778 if (!result)
2779 return win32_error("rename", NULL);
2780 Py_INCREF(Py_None);
2781 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002782#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002783 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002784#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002785}
2786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002787
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002788PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002789"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002791
Barry Warsaw53699e91996-12-10 23:23:01 +00002792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002793posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002794{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002795#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002796 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002797#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002798 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002799#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002800}
2801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002804"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002805Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002806
Barry Warsaw53699e91996-12-10 23:23:01 +00002807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002808posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002809{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002810#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002811 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002812#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002813 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002814#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002815}
2816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002817
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002818#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002819PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002820"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002821Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002822
Barry Warsaw53699e91996-12-10 23:23:01 +00002823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002824posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002825{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002826 char *command;
2827 long sts;
2828 if (!PyArg_ParseTuple(args, "s:system", &command))
2829 return NULL;
2830 Py_BEGIN_ALLOW_THREADS
2831 sts = system(command);
2832 Py_END_ALLOW_THREADS
2833 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002835#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002836
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002837
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002838PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002839"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002840Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841
Barry Warsaw53699e91996-12-10 23:23:01 +00002842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002843posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002844{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002845 int i;
2846 if (!PyArg_ParseTuple(args, "i:umask", &i))
2847 return NULL;
2848 i = (int)umask(i);
2849 if (i < 0)
2850 return posix_error();
2851 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002852}
2853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002854
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002855PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002856"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002857Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002858
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002859PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002860"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002861Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002862
Barry Warsaw53699e91996-12-10 23:23:01 +00002863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002864posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002865{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002866#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002867 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002868#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002869 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002870#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002871}
2872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002873
Guido van Rossumb6775db1994-08-01 11:34:53 +00002874#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002876"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002878
Barry Warsaw53699e91996-12-10 23:23:01 +00002879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002880posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002881{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002882 struct utsname u;
2883 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002884
Victor Stinnerd6f85422010-05-05 23:33:33 +00002885 Py_BEGIN_ALLOW_THREADS
2886 res = uname(&u);
2887 Py_END_ALLOW_THREADS
2888 if (res < 0)
2889 return posix_error();
2890 return Py_BuildValue("(sssss)",
2891 u.sysname,
2892 u.nodename,
2893 u.release,
2894 u.version,
2895 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002896}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002897#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002898
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002899static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002900extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002901{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002902 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002903 if (PyFloat_Check(t)) {
2904 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002905 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002906 if (!intobj)
2907 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002908#if SIZEOF_TIME_T > SIZEOF_LONG
2909 intval = PyInt_AsUnsignedLongLongMask(intobj);
2910#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002911 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002912#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002913 Py_DECREF(intobj);
2914 if (intval == -1 && PyErr_Occurred())
2915 return -1;
2916 *sec = intval;
2917 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2918 if (*usec < 0)
2919 /* If rounding gave us a negative number,
2920 truncate. */
2921 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002922 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002923 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002924#if SIZEOF_TIME_T > SIZEOF_LONG
2925 intval = PyInt_AsUnsignedLongLongMask(t);
2926#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002927 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002928#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002929 if (intval == -1 && PyErr_Occurred())
2930 return -1;
2931 *sec = intval;
2932 *usec = 0;
2933 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002934}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002935
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002937"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002938utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002939Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002940second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002941
Barry Warsaw53699e91996-12-10 23:23:01 +00002942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002943posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002944{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002945#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002946 PyObject *arg;
2947 PyUnicodeObject *obwpath;
2948 wchar_t *wpath = NULL;
2949 char *apath = NULL;
2950 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002951 time_t atimesec, mtimesec;
2952 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002953 FILETIME atime, mtime;
2954 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002955
Victor Stinnerd6f85422010-05-05 23:33:33 +00002956 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2957 wpath = PyUnicode_AS_UNICODE(obwpath);
2958 Py_BEGIN_ALLOW_THREADS
2959 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2960 NULL, OPEN_EXISTING,
2961 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2962 Py_END_ALLOW_THREADS
2963 if (hFile == INVALID_HANDLE_VALUE)
2964 return win32_error_unicode("utime", wpath);
2965 } else
2966 /* Drop the argument parsing error as narrow strings
2967 are also valid. */
2968 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002969
Victor Stinnerd6f85422010-05-05 23:33:33 +00002970 if (!wpath) {
2971 if (!PyArg_ParseTuple(args, "etO:utime",
2972 Py_FileSystemDefaultEncoding, &apath, &arg))
2973 return NULL;
2974 Py_BEGIN_ALLOW_THREADS
2975 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2976 NULL, OPEN_EXISTING,
2977 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2978 Py_END_ALLOW_THREADS
2979 if (hFile == INVALID_HANDLE_VALUE) {
2980 win32_error("utime", apath);
2981 PyMem_Free(apath);
2982 return NULL;
2983 }
2984 PyMem_Free(apath);
2985 }
2986
2987 if (arg == Py_None) {
2988 SYSTEMTIME now;
2989 GetSystemTime(&now);
2990 if (!SystemTimeToFileTime(&now, &mtime) ||
2991 !SystemTimeToFileTime(&now, &atime)) {
2992 win32_error("utime", NULL);
2993 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00002994 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00002995 }
2996 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2997 PyErr_SetString(PyExc_TypeError,
2998 "utime() arg 2 must be a tuple (atime, mtime)");
2999 goto done;
3000 }
3001 else {
3002 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3003 &atimesec, &ausec) == -1)
3004 goto done;
3005 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3006 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3007 &mtimesec, &musec) == -1)
3008 goto done;
3009 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3010 }
3011 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3012 /* Avoid putting the file name into the error here,
3013 as that may confuse the user into believing that
3014 something is wrong with the file, when it also
3015 could be the time stamp that gives a problem. */
3016 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00003017 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003018 }
3019 Py_INCREF(Py_None);
3020 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003021done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003022 CloseHandle(hFile);
3023 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003024#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003025
Victor Stinnerd6f85422010-05-05 23:33:33 +00003026 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00003027 time_t atime, mtime;
3028 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003029 int res;
3030 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003031
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003032#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003033 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003034#define ATIME buf[0].tv_sec
3035#define MTIME buf[1].tv_sec
3036#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003037/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003038 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003039#define ATIME buf.actime
3040#define MTIME buf.modtime
3041#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003042#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003043 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003044#define ATIME buf[0]
3045#define MTIME buf[1]
3046#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003047#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003048
Mark Hammond817c9292003-12-03 01:22:38 +00003049
Victor Stinnerd6f85422010-05-05 23:33:33 +00003050 if (!PyArg_ParseTuple(args, "etO:utime",
3051 Py_FileSystemDefaultEncoding, &path, &arg))
3052 return NULL;
3053 if (arg == Py_None) {
3054 /* optional time values not given */
3055 Py_BEGIN_ALLOW_THREADS
3056 res = utime(path, NULL);
3057 Py_END_ALLOW_THREADS
3058 }
3059 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3060 PyErr_SetString(PyExc_TypeError,
3061 "utime() arg 2 must be a tuple (atime, mtime)");
3062 PyMem_Free(path);
3063 return NULL;
3064 }
3065 else {
3066 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3067 &atime, &ausec) == -1) {
3068 PyMem_Free(path);
3069 return NULL;
3070 }
3071 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3072 &mtime, &musec) == -1) {
3073 PyMem_Free(path);
3074 return NULL;
3075 }
3076 ATIME = atime;
3077 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003078#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00003079 buf[0].tv_usec = ausec;
3080 buf[1].tv_usec = musec;
3081 Py_BEGIN_ALLOW_THREADS
3082 res = utimes(path, buf);
3083 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003084#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003085 Py_BEGIN_ALLOW_THREADS
3086 res = utime(path, UTIME_ARG);
3087 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003088#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003089 }
3090 if (res < 0) {
3091 return posix_error_with_allocated_filename(path);
3092 }
3093 PyMem_Free(path);
3094 Py_INCREF(Py_None);
3095 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003096#undef UTIME_ARG
3097#undef ATIME
3098#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003099#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003100}
3101
Guido van Rossum85e3b011991-06-03 12:42:10 +00003102
Guido van Rossum3b066191991-06-04 19:40:25 +00003103/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003105PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003106"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003107Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003108
Barry Warsaw53699e91996-12-10 23:23:01 +00003109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003110posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003111{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003112 int sts;
3113 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3114 return NULL;
3115 _exit(sts);
3116 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003117}
3118
Martin v. Löwis114619e2002-10-07 06:44:21 +00003119#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3120static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003121free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003122{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003123 Py_ssize_t i;
3124 for (i = 0; i < count; i++)
3125 PyMem_Free(array[i]);
3126 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003127}
3128#endif
3129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003130
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003131#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003132PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003133"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003134Execute an executable path with arguments, replacing current process.\n\
3135\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003136 path: path of executable file\n\
3137 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003138
Barry Warsaw53699e91996-12-10 23:23:01 +00003139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003140posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003141{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003142 char *path;
3143 PyObject *argv;
3144 char **argvlist;
3145 Py_ssize_t i, argc;
3146 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003147
Victor Stinnerd6f85422010-05-05 23:33:33 +00003148 /* execv has two arguments: (path, argv), where
3149 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003150
Victor Stinnerd6f85422010-05-05 23:33:33 +00003151 if (!PyArg_ParseTuple(args, "etO:execv",
3152 Py_FileSystemDefaultEncoding,
3153 &path, &argv))
3154 return NULL;
3155 if (PyList_Check(argv)) {
3156 argc = PyList_Size(argv);
3157 getitem = PyList_GetItem;
3158 }
3159 else if (PyTuple_Check(argv)) {
3160 argc = PyTuple_Size(argv);
3161 getitem = PyTuple_GetItem;
3162 }
3163 else {
3164 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3165 PyMem_Free(path);
3166 return NULL;
3167 }
3168 if (argc < 1) {
3169 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3170 PyMem_Free(path);
3171 return NULL;
3172 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003173
Victor Stinnerd6f85422010-05-05 23:33:33 +00003174 argvlist = PyMem_NEW(char *, argc+1);
3175 if (argvlist == NULL) {
3176 PyMem_Free(path);
3177 return PyErr_NoMemory();
3178 }
3179 for (i = 0; i < argc; i++) {
3180 if (!PyArg_Parse((*getitem)(argv, i), "et",
3181 Py_FileSystemDefaultEncoding,
3182 &argvlist[i])) {
3183 free_string_array(argvlist, i);
3184 PyErr_SetString(PyExc_TypeError,
3185 "execv() arg 2 must contain only strings");
3186 PyMem_Free(path);
3187 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003188
Victor Stinnerd6f85422010-05-05 23:33:33 +00003189 }
3190 }
3191 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003192
Victor Stinnerd6f85422010-05-05 23:33:33 +00003193 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003194
Victor Stinnerd6f85422010-05-05 23:33:33 +00003195 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003196
Victor Stinnerd6f85422010-05-05 23:33:33 +00003197 free_string_array(argvlist, argc);
3198 PyMem_Free(path);
3199 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003200}
3201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003203PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003204"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205Execute a path with arguments and environment, replacing current process.\n\
3206\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003207 path: path of executable file\n\
3208 args: tuple or list of arguments\n\
3209 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003210
Barry Warsaw53699e91996-12-10 23:23:01 +00003211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003212posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003213{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003214 char *path;
3215 PyObject *argv, *env;
3216 char **argvlist;
3217 char **envlist;
3218 PyObject *key, *val, *keys=NULL, *vals=NULL;
3219 Py_ssize_t i, pos, argc, envc;
3220 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3221 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003222
Victor Stinnerd6f85422010-05-05 23:33:33 +00003223 /* execve has three arguments: (path, argv, env), where
3224 argv is a list or tuple of strings and env is a dictionary
3225 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003226
Victor Stinnerd6f85422010-05-05 23:33:33 +00003227 if (!PyArg_ParseTuple(args, "etOO:execve",
3228 Py_FileSystemDefaultEncoding,
3229 &path, &argv, &env))
3230 return NULL;
3231 if (PyList_Check(argv)) {
3232 argc = PyList_Size(argv);
3233 getitem = PyList_GetItem;
3234 }
3235 else if (PyTuple_Check(argv)) {
3236 argc = PyTuple_Size(argv);
3237 getitem = PyTuple_GetItem;
3238 }
3239 else {
3240 PyErr_SetString(PyExc_TypeError,
3241 "execve() arg 2 must be a tuple or list");
3242 goto fail_0;
3243 }
3244 if (!PyMapping_Check(env)) {
3245 PyErr_SetString(PyExc_TypeError,
3246 "execve() arg 3 must be a mapping object");
3247 goto fail_0;
3248 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003249
Victor Stinnerd6f85422010-05-05 23:33:33 +00003250 argvlist = PyMem_NEW(char *, argc+1);
3251 if (argvlist == NULL) {
3252 PyErr_NoMemory();
3253 goto fail_0;
3254 }
3255 for (i = 0; i < argc; i++) {
3256 if (!PyArg_Parse((*getitem)(argv, i),
3257 "et;execve() arg 2 must contain only strings",
3258 Py_FileSystemDefaultEncoding,
3259 &argvlist[i]))
3260 {
3261 lastarg = i;
3262 goto fail_1;
3263 }
3264 }
3265 lastarg = argc;
3266 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003267
Victor Stinnerd6f85422010-05-05 23:33:33 +00003268 i = PyMapping_Size(env);
3269 if (i < 0)
3270 goto fail_1;
3271 envlist = PyMem_NEW(char *, i + 1);
3272 if (envlist == NULL) {
3273 PyErr_NoMemory();
3274 goto fail_1;
3275 }
3276 envc = 0;
3277 keys = PyMapping_Keys(env);
3278 vals = PyMapping_Values(env);
3279 if (!keys || !vals)
3280 goto fail_2;
3281 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3282 PyErr_SetString(PyExc_TypeError,
3283 "execve(): env.keys() or env.values() is not a list");
3284 goto fail_2;
3285 }
Tim Peters5aa91602002-01-30 05:46:57 +00003286
Victor Stinnerd6f85422010-05-05 23:33:33 +00003287 for (pos = 0; pos < i; pos++) {
3288 char *p, *k, *v;
3289 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003290
Victor Stinnerd6f85422010-05-05 23:33:33 +00003291 key = PyList_GetItem(keys, pos);
3292 val = PyList_GetItem(vals, pos);
3293 if (!key || !val)
3294 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003295
Victor Stinnerd6f85422010-05-05 23:33:33 +00003296 if (!PyArg_Parse(
3297 key,
3298 "s;execve() arg 3 contains a non-string key",
3299 &k) ||
3300 !PyArg_Parse(
3301 val,
3302 "s;execve() arg 3 contains a non-string value",
3303 &v))
3304 {
3305 goto fail_2;
3306 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003307
3308#if defined(PYOS_OS2)
3309 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3310 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3311#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003312 len = PyString_Size(key) + PyString_Size(val) + 2;
3313 p = PyMem_NEW(char, len);
3314 if (p == NULL) {
3315 PyErr_NoMemory();
3316 goto fail_2;
3317 }
3318 PyOS_snprintf(p, len, "%s=%s", k, v);
3319 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003320#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003321 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003322#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003323 }
3324 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003325
Victor Stinnerd6f85422010-05-05 23:33:33 +00003326 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003327
Victor Stinnerd6f85422010-05-05 23:33:33 +00003328 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003329
Victor Stinnerd6f85422010-05-05 23:33:33 +00003330 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003331
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003332 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003333 while (--envc >= 0)
3334 PyMem_DEL(envlist[envc]);
3335 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003336 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003337 free_string_array(argvlist, lastarg);
3338 Py_XDECREF(vals);
3339 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003340 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003341 PyMem_Free(path);
3342 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003343}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003344#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
Guido van Rossuma1065681999-01-25 23:20:23 +00003347#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003348PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003349"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003350Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003351\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003352 mode: mode of process creation\n\
3353 path: path of executable file\n\
3354 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003355
3356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003357posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003358{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003359 char *path;
3360 PyObject *argv;
3361 char **argvlist;
3362 int mode, i;
3363 Py_ssize_t argc;
3364 Py_intptr_t spawnval;
3365 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003366
Victor Stinnerd6f85422010-05-05 23:33:33 +00003367 /* spawnv has three arguments: (mode, path, argv), where
3368 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003369
Victor Stinnerd6f85422010-05-05 23:33:33 +00003370 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3371 Py_FileSystemDefaultEncoding,
3372 &path, &argv))
3373 return NULL;
3374 if (PyList_Check(argv)) {
3375 argc = PyList_Size(argv);
3376 getitem = PyList_GetItem;
3377 }
3378 else if (PyTuple_Check(argv)) {
3379 argc = PyTuple_Size(argv);
3380 getitem = PyTuple_GetItem;
3381 }
3382 else {
3383 PyErr_SetString(PyExc_TypeError,
3384 "spawnv() arg 2 must be a tuple or list");
3385 PyMem_Free(path);
3386 return NULL;
3387 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003388
Victor Stinnerd6f85422010-05-05 23:33:33 +00003389 argvlist = PyMem_NEW(char *, argc+1);
3390 if (argvlist == NULL) {
3391 PyMem_Free(path);
3392 return PyErr_NoMemory();
3393 }
3394 for (i = 0; i < argc; i++) {
3395 if (!PyArg_Parse((*getitem)(argv, i), "et",
3396 Py_FileSystemDefaultEncoding,
3397 &argvlist[i])) {
3398 free_string_array(argvlist, i);
3399 PyErr_SetString(
3400 PyExc_TypeError,
3401 "spawnv() arg 2 must contain only strings");
3402 PyMem_Free(path);
3403 return NULL;
3404 }
3405 }
3406 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003407
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003408#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003409 Py_BEGIN_ALLOW_THREADS
3410 spawnval = spawnv(mode, path, argvlist);
3411 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003412#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003413 if (mode == _OLD_P_OVERLAY)
3414 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003415
Victor Stinnerd6f85422010-05-05 23:33:33 +00003416 Py_BEGIN_ALLOW_THREADS
3417 spawnval = _spawnv(mode, path, argvlist);
3418 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003419#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003420
Victor Stinnerd6f85422010-05-05 23:33:33 +00003421 free_string_array(argvlist, argc);
3422 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003423
Victor Stinnerd6f85422010-05-05 23:33:33 +00003424 if (spawnval == -1)
3425 return posix_error();
3426 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003427#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003428 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003429#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003430 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003431#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003432}
3433
3434
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003436"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003437Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003438\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003439 mode: mode of process creation\n\
3440 path: path of executable file\n\
3441 args: tuple or list of arguments\n\
3442 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003443
3444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003445posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003446{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003447 char *path;
3448 PyObject *argv, *env;
3449 char **argvlist;
3450 char **envlist;
3451 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3452 int mode, pos, envc;
3453 Py_ssize_t argc, i;
3454 Py_intptr_t spawnval;
3455 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3456 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003457
Victor Stinnerd6f85422010-05-05 23:33:33 +00003458 /* spawnve has four arguments: (mode, path, argv, env), where
3459 argv is a list or tuple of strings and env is a dictionary
3460 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003461
Victor Stinnerd6f85422010-05-05 23:33:33 +00003462 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3463 Py_FileSystemDefaultEncoding,
3464 &path, &argv, &env))
3465 return NULL;
3466 if (PyList_Check(argv)) {
3467 argc = PyList_Size(argv);
3468 getitem = PyList_GetItem;
3469 }
3470 else if (PyTuple_Check(argv)) {
3471 argc = PyTuple_Size(argv);
3472 getitem = PyTuple_GetItem;
3473 }
3474 else {
3475 PyErr_SetString(PyExc_TypeError,
3476 "spawnve() arg 2 must be a tuple or list");
3477 goto fail_0;
3478 }
3479 if (!PyMapping_Check(env)) {
3480 PyErr_SetString(PyExc_TypeError,
3481 "spawnve() arg 3 must be a mapping object");
3482 goto fail_0;
3483 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003484
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 argvlist = PyMem_NEW(char *, argc+1);
3486 if (argvlist == NULL) {
3487 PyErr_NoMemory();
3488 goto fail_0;
3489 }
3490 for (i = 0; i < argc; i++) {
3491 if (!PyArg_Parse((*getitem)(argv, i),
3492 "et;spawnve() arg 2 must contain only strings",
3493 Py_FileSystemDefaultEncoding,
3494 &argvlist[i]))
3495 {
3496 lastarg = i;
3497 goto fail_1;
3498 }
3499 }
3500 lastarg = argc;
3501 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003502
Victor Stinnerd6f85422010-05-05 23:33:33 +00003503 i = PyMapping_Size(env);
3504 if (i < 0)
3505 goto fail_1;
3506 envlist = PyMem_NEW(char *, i + 1);
3507 if (envlist == NULL) {
3508 PyErr_NoMemory();
3509 goto fail_1;
3510 }
3511 envc = 0;
3512 keys = PyMapping_Keys(env);
3513 vals = PyMapping_Values(env);
3514 if (!keys || !vals)
3515 goto fail_2;
3516 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3517 PyErr_SetString(PyExc_TypeError,
3518 "spawnve(): env.keys() or env.values() is not a list");
3519 goto fail_2;
3520 }
Tim Peters5aa91602002-01-30 05:46:57 +00003521
Victor Stinnerd6f85422010-05-05 23:33:33 +00003522 for (pos = 0; pos < i; pos++) {
3523 char *p, *k, *v;
3524 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003525
Victor Stinnerd6f85422010-05-05 23:33:33 +00003526 key = PyList_GetItem(keys, pos);
3527 val = PyList_GetItem(vals, pos);
3528 if (!key || !val)
3529 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003530
Victor Stinnerd6f85422010-05-05 23:33:33 +00003531 if (!PyArg_Parse(
3532 key,
3533 "s;spawnve() arg 3 contains a non-string key",
3534 &k) ||
3535 !PyArg_Parse(
3536 val,
3537 "s;spawnve() arg 3 contains a non-string value",
3538 &v))
3539 {
3540 goto fail_2;
3541 }
3542 len = PyString_Size(key) + PyString_Size(val) + 2;
3543 p = PyMem_NEW(char, len);
3544 if (p == NULL) {
3545 PyErr_NoMemory();
3546 goto fail_2;
3547 }
3548 PyOS_snprintf(p, len, "%s=%s", k, v);
3549 envlist[envc++] = p;
3550 }
3551 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003552
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003553#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003554 Py_BEGIN_ALLOW_THREADS
3555 spawnval = spawnve(mode, path, argvlist, envlist);
3556 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003557#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003558 if (mode == _OLD_P_OVERLAY)
3559 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003560
Victor Stinnerd6f85422010-05-05 23:33:33 +00003561 Py_BEGIN_ALLOW_THREADS
3562 spawnval = _spawnve(mode, path, argvlist, envlist);
3563 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003564#endif
Tim Peters25059d32001-12-07 20:35:43 +00003565
Victor Stinnerd6f85422010-05-05 23:33:33 +00003566 if (spawnval == -1)
3567 (void) posix_error();
3568 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003569#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003570 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003571#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003572 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003573#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003574
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003575 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003576 while (--envc >= 0)
3577 PyMem_DEL(envlist[envc]);
3578 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003579 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003580 free_string_array(argvlist, lastarg);
3581 Py_XDECREF(vals);
3582 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003583 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003584 PyMem_Free(path);
3585 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003586}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003587
3588/* OS/2 supports spawnvp & spawnvpe natively */
3589#if defined(PYOS_OS2)
3590PyDoc_STRVAR(posix_spawnvp__doc__,
3591"spawnvp(mode, file, args)\n\n\
3592Execute the program 'file' in a new process, using the environment\n\
3593search path to find the file.\n\
3594\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 mode: mode of process creation\n\
3596 file: executable file name\n\
3597 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003598
3599static PyObject *
3600posix_spawnvp(PyObject *self, PyObject *args)
3601{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003602 char *path;
3603 PyObject *argv;
3604 char **argvlist;
3605 int mode, i, argc;
3606 Py_intptr_t spawnval;
3607 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003608
Victor Stinnerd6f85422010-05-05 23:33:33 +00003609 /* spawnvp has three arguments: (mode, path, argv), where
3610 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003611
Victor Stinnerd6f85422010-05-05 23:33:33 +00003612 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3613 Py_FileSystemDefaultEncoding,
3614 &path, &argv))
3615 return NULL;
3616 if (PyList_Check(argv)) {
3617 argc = PyList_Size(argv);
3618 getitem = PyList_GetItem;
3619 }
3620 else if (PyTuple_Check(argv)) {
3621 argc = PyTuple_Size(argv);
3622 getitem = PyTuple_GetItem;
3623 }
3624 else {
3625 PyErr_SetString(PyExc_TypeError,
3626 "spawnvp() arg 2 must be a tuple or list");
3627 PyMem_Free(path);
3628 return NULL;
3629 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003630
Victor Stinnerd6f85422010-05-05 23:33:33 +00003631 argvlist = PyMem_NEW(char *, argc+1);
3632 if (argvlist == NULL) {
3633 PyMem_Free(path);
3634 return PyErr_NoMemory();
3635 }
3636 for (i = 0; i < argc; i++) {
3637 if (!PyArg_Parse((*getitem)(argv, i), "et",
3638 Py_FileSystemDefaultEncoding,
3639 &argvlist[i])) {
3640 free_string_array(argvlist, i);
3641 PyErr_SetString(
3642 PyExc_TypeError,
3643 "spawnvp() arg 2 must contain only strings");
3644 PyMem_Free(path);
3645 return NULL;
3646 }
3647 }
3648 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003649
Victor Stinnerd6f85422010-05-05 23:33:33 +00003650 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003651#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003652 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003653#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003654 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003655#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003656 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003657
Victor Stinnerd6f85422010-05-05 23:33:33 +00003658 free_string_array(argvlist, argc);
3659 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003660
Victor Stinnerd6f85422010-05-05 23:33:33 +00003661 if (spawnval == -1)
3662 return posix_error();
3663 else
3664 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003665}
3666
3667
3668PyDoc_STRVAR(posix_spawnvpe__doc__,
3669"spawnvpe(mode, file, args, env)\n\n\
3670Execute the program 'file' in a new process, using the environment\n\
3671search path to find the file.\n\
3672\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003673 mode: mode of process creation\n\
3674 file: executable file name\n\
3675 args: tuple or list of arguments\n\
3676 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003677
3678static PyObject *
3679posix_spawnvpe(PyObject *self, PyObject *args)
3680{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003681 char *path;
3682 PyObject *argv, *env;
3683 char **argvlist;
3684 char **envlist;
3685 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3686 int mode, i, pos, argc, envc;
3687 Py_intptr_t spawnval;
3688 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3689 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003690
Victor Stinnerd6f85422010-05-05 23:33:33 +00003691 /* spawnvpe has four arguments: (mode, path, argv, env), where
3692 argv is a list or tuple of strings and env is a dictionary
3693 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003694
Victor Stinnerd6f85422010-05-05 23:33:33 +00003695 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3696 Py_FileSystemDefaultEncoding,
3697 &path, &argv, &env))
3698 return NULL;
3699 if (PyList_Check(argv)) {
3700 argc = PyList_Size(argv);
3701 getitem = PyList_GetItem;
3702 }
3703 else if (PyTuple_Check(argv)) {
3704 argc = PyTuple_Size(argv);
3705 getitem = PyTuple_GetItem;
3706 }
3707 else {
3708 PyErr_SetString(PyExc_TypeError,
3709 "spawnvpe() arg 2 must be a tuple or list");
3710 goto fail_0;
3711 }
3712 if (!PyMapping_Check(env)) {
3713 PyErr_SetString(PyExc_TypeError,
3714 "spawnvpe() arg 3 must be a mapping object");
3715 goto fail_0;
3716 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003717
Victor Stinnerd6f85422010-05-05 23:33:33 +00003718 argvlist = PyMem_NEW(char *, argc+1);
3719 if (argvlist == NULL) {
3720 PyErr_NoMemory();
3721 goto fail_0;
3722 }
3723 for (i = 0; i < argc; i++) {
3724 if (!PyArg_Parse((*getitem)(argv, i),
3725 "et;spawnvpe() arg 2 must contain only strings",
3726 Py_FileSystemDefaultEncoding,
3727 &argvlist[i]))
3728 {
3729 lastarg = i;
3730 goto fail_1;
3731 }
3732 }
3733 lastarg = argc;
3734 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003735
Victor Stinnerd6f85422010-05-05 23:33:33 +00003736 i = PyMapping_Size(env);
3737 if (i < 0)
3738 goto fail_1;
3739 envlist = PyMem_NEW(char *, i + 1);
3740 if (envlist == NULL) {
3741 PyErr_NoMemory();
3742 goto fail_1;
3743 }
3744 envc = 0;
3745 keys = PyMapping_Keys(env);
3746 vals = PyMapping_Values(env);
3747 if (!keys || !vals)
3748 goto fail_2;
3749 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3750 PyErr_SetString(PyExc_TypeError,
3751 "spawnvpe(): env.keys() or env.values() is not a list");
3752 goto fail_2;
3753 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003754
Victor Stinnerd6f85422010-05-05 23:33:33 +00003755 for (pos = 0; pos < i; pos++) {
3756 char *p, *k, *v;
3757 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003758
Victor Stinnerd6f85422010-05-05 23:33:33 +00003759 key = PyList_GetItem(keys, pos);
3760 val = PyList_GetItem(vals, pos);
3761 if (!key || !val)
3762 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003763
Victor Stinnerd6f85422010-05-05 23:33:33 +00003764 if (!PyArg_Parse(
3765 key,
3766 "s;spawnvpe() arg 3 contains a non-string key",
3767 &k) ||
3768 !PyArg_Parse(
3769 val,
3770 "s;spawnvpe() arg 3 contains a non-string value",
3771 &v))
3772 {
3773 goto fail_2;
3774 }
3775 len = PyString_Size(key) + PyString_Size(val) + 2;
3776 p = PyMem_NEW(char, len);
3777 if (p == NULL) {
3778 PyErr_NoMemory();
3779 goto fail_2;
3780 }
3781 PyOS_snprintf(p, len, "%s=%s", k, v);
3782 envlist[envc++] = p;
3783 }
3784 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003785
Victor Stinnerd6f85422010-05-05 23:33:33 +00003786 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003787#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003788 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003789#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003790 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003792 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003793
Victor Stinnerd6f85422010-05-05 23:33:33 +00003794 if (spawnval == -1)
3795 (void) posix_error();
3796 else
3797 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003798
3799 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003800 while (--envc >= 0)
3801 PyMem_DEL(envlist[envc]);
3802 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003803 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003804 free_string_array(argvlist, lastarg);
3805 Py_XDECREF(vals);
3806 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003807 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003808 PyMem_Free(path);
3809 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003810}
3811#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003812#endif /* HAVE_SPAWNV */
3813
3814
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003815#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003816PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003817"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003818Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3819\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003821
3822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003823posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003824{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003825 pid_t pid;
3826 int result = 0;
3827 _PyImport_AcquireLock();
3828 pid = fork1();
3829 if (pid == 0) {
3830 /* child: this clobbers and resets the import lock. */
3831 PyOS_AfterFork();
3832 } else {
3833 /* parent: release the import lock. */
3834 result = _PyImport_ReleaseLock();
3835 }
3836 if (pid == -1)
3837 return posix_error();
3838 if (result < 0) {
3839 /* Don't clobber the OSError if the fork failed. */
3840 PyErr_SetString(PyExc_RuntimeError,
3841 "not holding the import lock");
3842 return NULL;
3843 }
3844 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003845}
3846#endif
3847
3848
Guido van Rossumad0ee831995-03-01 10:34:45 +00003849#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003851"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003852Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003853Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003854
Barry Warsaw53699e91996-12-10 23:23:01 +00003855static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003856posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003857{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003858 pid_t pid;
3859 int result = 0;
3860 _PyImport_AcquireLock();
3861 pid = fork();
3862 if (pid == 0) {
3863 /* child: this clobbers and resets the import lock. */
3864 PyOS_AfterFork();
3865 } else {
3866 /* parent: release the import lock. */
3867 result = _PyImport_ReleaseLock();
3868 }
3869 if (pid == -1)
3870 return posix_error();
3871 if (result < 0) {
3872 /* Don't clobber the OSError if the fork failed. */
3873 PyErr_SetString(PyExc_RuntimeError,
3874 "not holding the import lock");
3875 return NULL;
3876 }
3877 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003878}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003879#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003880
Neal Norwitzb59798b2003-03-21 01:43:31 +00003881/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003882/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3883#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003884#define DEV_PTY_FILE "/dev/ptc"
3885#define HAVE_DEV_PTMX
3886#else
3887#define DEV_PTY_FILE "/dev/ptmx"
3888#endif
3889
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003890#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003891#ifdef HAVE_PTY_H
3892#include <pty.h>
3893#else
3894#ifdef HAVE_LIBUTIL_H
3895#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003896#else
3897#ifdef HAVE_UTIL_H
3898#include <util.h>
3899#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003900#endif /* HAVE_LIBUTIL_H */
3901#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003902#ifdef HAVE_STROPTS_H
3903#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003904#endif
3905#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003906
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003907#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003909"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003911
3912static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003913posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003914{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003915 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003916#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003917 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003918#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003919#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003920 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003921#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003922 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003923#endif
3924#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003925
Thomas Wouters70c21a12000-07-14 14:28:33 +00003926#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003927 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3928 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003929#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003930 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3931 if (slave_name == NULL)
3932 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003933
Victor Stinnerd6f85422010-05-05 23:33:33 +00003934 slave_fd = open(slave_name, O_RDWR);
3935 if (slave_fd < 0)
3936 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003937#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003938 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3939 if (master_fd < 0)
3940 return posix_error();
3941 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3942 /* change permission of slave */
3943 if (grantpt(master_fd) < 0) {
3944 PyOS_setsig(SIGCHLD, sig_saved);
3945 return posix_error();
3946 }
3947 /* unlock slave */
3948 if (unlockpt(master_fd) < 0) {
3949 PyOS_setsig(SIGCHLD, sig_saved);
3950 return posix_error();
3951 }
3952 PyOS_setsig(SIGCHLD, sig_saved);
3953 slave_name = ptsname(master_fd); /* get name of slave */
3954 if (slave_name == NULL)
3955 return posix_error();
3956 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3957 if (slave_fd < 0)
3958 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003959#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003960 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3961 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003962#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003963 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003964#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003965#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003966#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003967
Victor Stinnerd6f85422010-05-05 23:33:33 +00003968 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003969
Fred Drake8cef4cf2000-06-28 16:40:38 +00003970}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003971#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003972
3973#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003974PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003975"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003976Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3977Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003978To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003979
3980static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003981posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003982{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003983 int master_fd = -1, result = 0;
3984 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003985
Victor Stinnerd6f85422010-05-05 23:33:33 +00003986 _PyImport_AcquireLock();
3987 pid = forkpty(&master_fd, NULL, NULL, NULL);
3988 if (pid == 0) {
3989 /* child: this clobbers and resets the import lock. */
3990 PyOS_AfterFork();
3991 } else {
3992 /* parent: release the import lock. */
3993 result = _PyImport_ReleaseLock();
3994 }
3995 if (pid == -1)
3996 return posix_error();
3997 if (result < 0) {
3998 /* Don't clobber the OSError if the fork failed. */
3999 PyErr_SetString(PyExc_RuntimeError,
4000 "not holding the import lock");
4001 return NULL;
4002 }
4003 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004004}
4005#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004006
Guido van Rossumad0ee831995-03-01 10:34:45 +00004007#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004009"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004010Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004011
Barry Warsaw53699e91996-12-10 23:23:01 +00004012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004013posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004014{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004015 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004016}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004017#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004019
Guido van Rossumad0ee831995-03-01 10:34:45 +00004020#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004021PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004022"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004023Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004024
Barry Warsaw53699e91996-12-10 23:23:01 +00004025static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004026posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004027{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004028 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004029}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004030#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004032
Guido van Rossumad0ee831995-03-01 10:34:45 +00004033#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004035"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004036Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004037
Barry Warsaw53699e91996-12-10 23:23:01 +00004038static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004039posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004040{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004041 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004042}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004043#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004045
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004047"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004048Return the current process 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_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004052{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004053 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054}
4055
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004056
Fred Drakec9680921999-12-13 16:37:25 +00004057#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004059"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004060Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004061
4062static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004063posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004064{
4065 PyObject *result = NULL;
4066
Fred Drakec9680921999-12-13 16:37:25 +00004067#ifdef NGROUPS_MAX
4068#define MAX_GROUPS NGROUPS_MAX
4069#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004070 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004071#define MAX_GROUPS 64
4072#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004073 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004074
Victor Stinner59729ff2011-07-05 11:28:19 +02004075 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004076 * This is a helper variable to store the intermediate result when
4077 * that happens.
4078 *
4079 * To keep the code readable the OSX behaviour is unconditional,
4080 * according to the POSIX spec this should be safe on all unix-y
4081 * systems.
4082 */
4083 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004084 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004085
Ned Deily80743642013-08-01 21:19:09 -07004086#ifdef __APPLE__
4087 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4088 * there are more groups than can fit in grouplist. Therefore, on OS X
4089 * always first call getgroups with length 0 to get the actual number
4090 * of groups.
4091 */
4092 n = getgroups(0, NULL);
4093 if (n < 0) {
4094 return posix_error();
4095 } else if (n <= MAX_GROUPS) {
4096 /* groups will fit in existing array */
4097 alt_grouplist = grouplist;
4098 } else {
4099 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4100 if (alt_grouplist == NULL) {
4101 errno = EINVAL;
4102 return posix_error();
4103 }
4104 }
4105
4106 n = getgroups(n, alt_grouplist);
4107 if (n == -1) {
4108 if (alt_grouplist != grouplist) {
4109 PyMem_Free(alt_grouplist);
4110 }
4111 return posix_error();
4112 }
4113#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004114 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004115 if (n < 0) {
4116 if (errno == EINVAL) {
4117 n = getgroups(0, NULL);
4118 if (n == -1) {
4119 return posix_error();
4120 }
4121 if (n == 0) {
4122 /* Avoid malloc(0) */
4123 alt_grouplist = grouplist;
4124 } else {
4125 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4126 if (alt_grouplist == NULL) {
4127 errno = EINVAL;
4128 return posix_error();
4129 }
4130 n = getgroups(n, alt_grouplist);
4131 if (n == -1) {
4132 PyMem_Free(alt_grouplist);
4133 return posix_error();
4134 }
4135 }
4136 } else {
4137 return posix_error();
4138 }
4139 }
Ned Deily80743642013-08-01 21:19:09 -07004140#endif
4141
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004142 result = PyList_New(n);
4143 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004144 int i;
4145 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004146 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004147 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004148 Py_DECREF(result);
4149 result = NULL;
4150 break;
Fred Drakec9680921999-12-13 16:37:25 +00004151 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004152 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004153 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004154 }
4155
4156 if (alt_grouplist != grouplist) {
4157 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004158 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004159
Fred Drakec9680921999-12-13 16:37:25 +00004160 return result;
4161}
4162#endif
4163
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004164#ifdef HAVE_INITGROUPS
4165PyDoc_STRVAR(posix_initgroups__doc__,
4166"initgroups(username, gid) -> None\n\n\
4167Call the system initgroups() to initialize the group access list with all of\n\
4168the groups of which the specified username is a member, plus the specified\n\
4169group id.");
4170
4171static PyObject *
4172posix_initgroups(PyObject *self, PyObject *args)
4173{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004174 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004175#ifdef __APPLE__
4176 int gid;
4177#else
4178 gid_t gid;
4179#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004180
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004181#ifdef __APPLE__
4182 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4183 &gid))
4184#else
4185 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4186 _Py_Gid_Converter, &gid))
4187#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004188 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004189
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004190 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004191 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004192
Victor Stinnerd6f85422010-05-05 23:33:33 +00004193 Py_INCREF(Py_None);
4194 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004195}
4196#endif
4197
Martin v. Löwis606edc12002-06-13 21:09:11 +00004198#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004199PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004200"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004201Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004202
4203static PyObject *
4204posix_getpgid(PyObject *self, PyObject *args)
4205{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004206 pid_t pid, pgid;
4207 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4208 return NULL;
4209 pgid = getpgid(pid);
4210 if (pgid < 0)
4211 return posix_error();
4212 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004213}
4214#endif /* HAVE_GETPGID */
4215
4216
Guido van Rossumb6775db1994-08-01 11:34:53 +00004217#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004218PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004219"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004220Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004221
Barry Warsaw53699e91996-12-10 23:23:01 +00004222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004223posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004224{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004225#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004226 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004227#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004228 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004229#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004230}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004231#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004233
Guido van Rossumb6775db1994-08-01 11:34:53 +00004234#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004235PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004236"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004237Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238
Barry Warsaw53699e91996-12-10 23:23:01 +00004239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004240posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004241{
Guido van Rossum64933891994-10-20 21:56:42 +00004242#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004243 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004244#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004245 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004246#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004247 return posix_error();
4248 Py_INCREF(Py_None);
4249 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004250}
4251
Guido van Rossumb6775db1994-08-01 11:34:53 +00004252#endif /* HAVE_SETPGRP */
4253
Guido van Rossumad0ee831995-03-01 10:34:45 +00004254#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004256"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004257Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Barry Warsaw53699e91996-12-10 23:23:01 +00004259static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004260posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004261{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004262 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004263}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004264#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Fred Drake12c6e2d1999-12-14 21:25:03 +00004267#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004268PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004269"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004270Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004271
4272static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004273posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004274{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004275 PyObject *result = NULL;
4276 char *name;
4277 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004278
Victor Stinnerd6f85422010-05-05 23:33:33 +00004279 errno = 0;
4280 name = getlogin();
4281 if (name == NULL) {
4282 if (errno)
4283 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004284 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004285 PyErr_SetString(PyExc_OSError,
4286 "unable to determine login name");
4287 }
4288 else
4289 result = PyString_FromString(name);
4290 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004291
Fred Drake12c6e2d1999-12-14 21:25:03 +00004292 return result;
4293}
4294#endif
4295
Guido van Rossumad0ee831995-03-01 10:34:45 +00004296#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004298"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Barry Warsaw53699e91996-12-10 23:23:01 +00004301static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004302posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004303{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004304 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004305}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004306#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004308
Guido van Rossumad0ee831995-03-01 10:34:45 +00004309#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004310PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004311"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004312Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004313
Barry Warsaw53699e91996-12-10 23:23:01 +00004314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004315posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004316{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004317 pid_t pid;
4318 int sig;
4319 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4320 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004321#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004322 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4323 APIRET rc;
4324 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004325 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004326
4327 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4328 APIRET rc;
4329 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004330 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004331
4332 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004333 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004334#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004335 if (kill(pid, sig) == -1)
4336 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004337#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004338 Py_INCREF(Py_None);
4339 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004340}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004341#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004342
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004343#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004344PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004345"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004347
4348static PyObject *
4349posix_killpg(PyObject *self, PyObject *args)
4350{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004351 int sig;
4352 pid_t pgid;
4353 /* XXX some man pages make the `pgid` parameter an int, others
4354 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4355 take the same type. Moreover, pid_t is always at least as wide as
4356 int (else compilation of this module fails), which is safe. */
4357 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4358 return NULL;
4359 if (killpg(pgid, sig) == -1)
4360 return posix_error();
4361 Py_INCREF(Py_None);
4362 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004363}
4364#endif
4365
Brian Curtine5aa8862010-04-02 23:26:06 +00004366#ifdef MS_WINDOWS
4367PyDoc_STRVAR(win32_kill__doc__,
4368"kill(pid, sig)\n\n\
4369Kill a process with a signal.");
4370
4371static PyObject *
4372win32_kill(PyObject *self, PyObject *args)
4373{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004374 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004375 DWORD pid, sig, err;
4376 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004377
Victor Stinnerd6f85422010-05-05 23:33:33 +00004378 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4379 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004380
Victor Stinnerd6f85422010-05-05 23:33:33 +00004381 /* Console processes which share a common console can be sent CTRL+C or
4382 CTRL+BREAK events, provided they handle said events. */
4383 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4384 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4385 err = GetLastError();
4386 return PyErr_SetFromWindowsErr(err);
4387 }
4388 else
4389 Py_RETURN_NONE;
4390 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004391
Victor Stinnerd6f85422010-05-05 23:33:33 +00004392 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4393 attempt to open and terminate the process. */
4394 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4395 if (handle == NULL) {
4396 err = GetLastError();
4397 return PyErr_SetFromWindowsErr(err);
4398 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004399
Victor Stinnerd6f85422010-05-05 23:33:33 +00004400 if (TerminateProcess(handle, sig) == 0) {
4401 err = GetLastError();
4402 result = PyErr_SetFromWindowsErr(err);
4403 } else {
4404 Py_INCREF(Py_None);
4405 result = Py_None;
4406 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004407
Victor Stinnerd6f85422010-05-05 23:33:33 +00004408 CloseHandle(handle);
4409 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004410}
Brian Curtincaea7e82011-06-08 19:29:53 -05004411
Brian Curtin5446f082011-06-09 10:00:42 -05004412PyDoc_STRVAR(posix__isdir__doc__,
4413"Return true if the pathname refers to an existing directory.");
4414
Brian Curtincaea7e82011-06-08 19:29:53 -05004415static PyObject *
4416posix__isdir(PyObject *self, PyObject *args)
4417{
4418 PyObject *opath;
4419 char *path;
4420 PyUnicodeObject *po;
4421 DWORD attributes;
4422
4423 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
4424 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
4425
4426 attributes = GetFileAttributesW(wpath);
4427 if (attributes == INVALID_FILE_ATTRIBUTES)
4428 Py_RETURN_FALSE;
4429 goto check;
4430 }
4431 /* Drop the argument parsing error as narrow strings
4432 are also valid. */
4433 PyErr_Clear();
4434
4435 if (!PyArg_ParseTuple(args, "et:_isdir",
4436 Py_FileSystemDefaultEncoding, &path))
4437 return NULL;
4438
4439 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004440 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004441 if (attributes == INVALID_FILE_ATTRIBUTES)
4442 Py_RETURN_FALSE;
4443
4444check:
4445 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4446 Py_RETURN_TRUE;
4447 else
4448 Py_RETURN_FALSE;
4449}
Brian Curtine5aa8862010-04-02 23:26:06 +00004450#endif /* MS_WINDOWS */
4451
Guido van Rossumc0125471996-06-28 18:55:32 +00004452#ifdef HAVE_PLOCK
4453
4454#ifdef HAVE_SYS_LOCK_H
4455#include <sys/lock.h>
4456#endif
4457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004458PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004459"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004460Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004461
Barry Warsaw53699e91996-12-10 23:23:01 +00004462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004463posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004464{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004465 int op;
4466 if (!PyArg_ParseTuple(args, "i:plock", &op))
4467 return NULL;
4468 if (plock(op) == -1)
4469 return posix_error();
4470 Py_INCREF(Py_None);
4471 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004472}
4473#endif
4474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004475
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004476#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004477PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004478"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004479Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004480
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004481#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004482#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004483static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004484async_system(const char *command)
4485{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004486 char errormsg[256], args[1024];
4487 RESULTCODES rcodes;
4488 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004489
Victor Stinnerd6f85422010-05-05 23:33:33 +00004490 char *shell = getenv("COMSPEC");
4491 if (!shell)
4492 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004493
Victor Stinnerd6f85422010-05-05 23:33:33 +00004494 /* avoid overflowing the argument buffer */
4495 if (strlen(shell) + 3 + strlen(command) >= 1024)
4496 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004497
Victor Stinnerd6f85422010-05-05 23:33:33 +00004498 args[0] = '\0';
4499 strcat(args, shell);
4500 strcat(args, "/c ");
4501 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004502
Victor Stinnerd6f85422010-05-05 23:33:33 +00004503 /* execute asynchronously, inheriting the environment */
4504 rc = DosExecPgm(errormsg,
4505 sizeof(errormsg),
4506 EXEC_ASYNC,
4507 args,
4508 NULL,
4509 &rcodes,
4510 shell);
4511 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004512}
4513
Guido van Rossumd48f2521997-12-05 22:19:34 +00004514static FILE *
4515popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004516{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004517 int oldfd, tgtfd;
4518 HFILE pipeh[2];
4519 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004520
Victor Stinnerd6f85422010-05-05 23:33:33 +00004521 /* mode determines which of stdin or stdout is reconnected to
4522 * the pipe to the child
4523 */
4524 if (strchr(mode, 'r') != NULL) {
4525 tgt_fd = 1; /* stdout */
4526 } else if (strchr(mode, 'w')) {
4527 tgt_fd = 0; /* stdin */
4528 } else {
4529 *err = ERROR_INVALID_ACCESS;
4530 return NULL;
4531 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004532
Victor Stinnerd6f85422010-05-05 23:33:33 +00004533 /* setup the pipe */
4534 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4535 *err = rc;
4536 return NULL;
4537 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004538
Victor Stinnerd6f85422010-05-05 23:33:33 +00004539 /* prevent other threads accessing stdio */
4540 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004541
Victor Stinnerd6f85422010-05-05 23:33:33 +00004542 /* reconnect stdio and execute child */
4543 oldfd = dup(tgtfd);
4544 close(tgtfd);
4545 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4546 DosClose(pipeh[tgtfd]);
4547 rc = async_system(command);
4548 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004549
Victor Stinnerd6f85422010-05-05 23:33:33 +00004550 /* restore stdio */
4551 dup2(oldfd, tgtfd);
4552 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004553
Victor Stinnerd6f85422010-05-05 23:33:33 +00004554 /* allow other threads access to stdio */
4555 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004556
Victor Stinnerd6f85422010-05-05 23:33:33 +00004557 /* if execution of child was successful return file stream */
4558 if (rc == NO_ERROR)
4559 return fdopen(pipeh[1 - tgtfd], mode);
4560 else {
4561 DosClose(pipeh[1 - tgtfd]);
4562 *err = rc;
4563 return NULL;
4564 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004565}
4566
4567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004568posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004569{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004570 char *name;
4571 char *mode = "r";
4572 int err, bufsize = -1;
4573 FILE *fp;
4574 PyObject *f;
4575 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4576 return NULL;
4577 Py_BEGIN_ALLOW_THREADS
4578 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4579 Py_END_ALLOW_THREADS
4580 if (fp == NULL)
4581 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004582
Victor Stinnerd6f85422010-05-05 23:33:33 +00004583 f = PyFile_FromFile(fp, name, mode, fclose);
4584 if (f != NULL)
4585 PyFile_SetBufSize(f, bufsize);
4586 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004587}
4588
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004589#elif defined(PYCC_GCC)
4590
4591/* standard posix version of popen() support */
4592static PyObject *
4593posix_popen(PyObject *self, PyObject *args)
4594{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004595 char *name;
4596 char *mode = "r";
4597 int 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);
4604 Py_END_ALLOW_THREADS
4605 if (fp == NULL)
4606 return posix_error();
4607 f = PyFile_FromFile(fp, name, mode, pclose);
4608 if (f != NULL)
4609 PyFile_SetBufSize(f, bufsize);
4610 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004611}
4612
4613/* fork() under OS/2 has lots'o'warts
4614 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4615 * most of this code is a ripoff of the win32 code, but using the
4616 * capabilities of EMX's C library routines
4617 */
4618
4619/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4620#define POPEN_1 1
4621#define POPEN_2 2
4622#define POPEN_3 3
4623#define POPEN_4 4
4624
4625static PyObject *_PyPopen(char *, int, int, int);
4626static int _PyPclose(FILE *file);
4627
4628/*
4629 * Internal dictionary mapping popen* file pointers to process handles,
4630 * for use when retrieving the process exit code. See _PyPclose() below
4631 * for more information on this dictionary's use.
4632 */
4633static PyObject *_PyPopenProcs = NULL;
4634
4635/* os2emx version of popen2()
4636 *
4637 * The result of this function is a pipe (file) connected to the
4638 * process's stdin, and a pipe connected to the process's stdout.
4639 */
4640
4641static PyObject *
4642os2emx_popen2(PyObject *self, PyObject *args)
4643{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004644 PyObject *f;
4645 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004646
Victor Stinnerd6f85422010-05-05 23:33:33 +00004647 char *cmdstring;
4648 char *mode = "t";
4649 int bufsize = -1;
4650 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4651 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004652
Victor Stinnerd6f85422010-05-05 23:33:33 +00004653 if (*mode == 't')
4654 tm = O_TEXT;
4655 else if (*mode != 'b') {
4656 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4657 return NULL;
4658 } else
4659 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004660
Victor Stinnerd6f85422010-05-05 23:33:33 +00004661 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004662
Victor Stinnerd6f85422010-05-05 23:33:33 +00004663 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004664}
4665
4666/*
4667 * Variation on os2emx.popen2
4668 *
4669 * The result of this function is 3 pipes - the process's stdin,
4670 * stdout and stderr
4671 */
4672
4673static PyObject *
4674os2emx_popen3(PyObject *self, PyObject *args)
4675{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004676 PyObject *f;
4677 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004678
Victor Stinnerd6f85422010-05-05 23:33:33 +00004679 char *cmdstring;
4680 char *mode = "t";
4681 int bufsize = -1;
4682 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4683 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004684
Victor Stinnerd6f85422010-05-05 23:33:33 +00004685 if (*mode == 't')
4686 tm = O_TEXT;
4687 else if (*mode != 'b') {
4688 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4689 return NULL;
4690 } else
4691 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004692
Victor Stinnerd6f85422010-05-05 23:33:33 +00004693 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004694
Victor Stinnerd6f85422010-05-05 23:33:33 +00004695 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004696}
4697
4698/*
4699 * Variation on os2emx.popen2
4700 *
Tim Peters11b23062003-04-23 02:39:17 +00004701 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004702 * and stdout+stderr combined as a single pipe.
4703 */
4704
4705static PyObject *
4706os2emx_popen4(PyObject *self, PyObject *args)
4707{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004708 PyObject *f;
4709 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004710
Victor Stinnerd6f85422010-05-05 23:33:33 +00004711 char *cmdstring;
4712 char *mode = "t";
4713 int bufsize = -1;
4714 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4715 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004716
Victor Stinnerd6f85422010-05-05 23:33:33 +00004717 if (*mode == 't')
4718 tm = O_TEXT;
4719 else if (*mode != 'b') {
4720 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4721 return NULL;
4722 } else
4723 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004724
Victor Stinnerd6f85422010-05-05 23:33:33 +00004725 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726
Victor Stinnerd6f85422010-05-05 23:33:33 +00004727 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004728}
4729
4730/* a couple of structures for convenient handling of multiple
4731 * file handles and pipes
4732 */
4733struct file_ref
4734{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004735 int handle;
4736 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004737};
4738
4739struct pipe_ref
4740{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004741 int rd;
4742 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004743};
4744
4745/* The following code is derived from the win32 code */
4746
4747static PyObject *
4748_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4749{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004750 struct file_ref stdio[3];
4751 struct pipe_ref p_fd[3];
4752 FILE *p_s[3];
4753 int file_count, i, pipe_err;
4754 pid_t pipe_pid;
4755 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4756 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004757
Victor Stinnerd6f85422010-05-05 23:33:33 +00004758 /* file modes for subsequent fdopen's on pipe handles */
4759 if (mode == O_TEXT)
4760 {
4761 rd_mode = "rt";
4762 wr_mode = "wt";
4763 }
4764 else
4765 {
4766 rd_mode = "rb";
4767 wr_mode = "wb";
4768 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004769
Victor Stinnerd6f85422010-05-05 23:33:33 +00004770 /* prepare shell references */
4771 if ((shell = getenv("EMXSHELL")) == NULL)
4772 if ((shell = getenv("COMSPEC")) == NULL)
4773 {
4774 errno = ENOENT;
4775 return posix_error();
4776 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004777
Victor Stinnerd6f85422010-05-05 23:33:33 +00004778 sh_name = _getname(shell);
4779 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4780 opt = "/c";
4781 else
4782 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004783
Victor Stinnerd6f85422010-05-05 23:33:33 +00004784 /* save current stdio fds + their flags, and set not inheritable */
4785 i = pipe_err = 0;
4786 while (pipe_err >= 0 && i < 3)
4787 {
4788 pipe_err = stdio[i].handle = dup(i);
4789 stdio[i].flags = fcntl(i, F_GETFD, 0);
4790 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4791 i++;
4792 }
4793 if (pipe_err < 0)
4794 {
4795 /* didn't get them all saved - clean up and bail out */
4796 int saved_err = errno;
4797 while (i-- > 0)
4798 {
4799 close(stdio[i].handle);
4800 }
4801 errno = saved_err;
4802 return posix_error();
4803 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004804
Victor Stinnerd6f85422010-05-05 23:33:33 +00004805 /* create pipe ends */
4806 file_count = 2;
4807 if (n == POPEN_3)
4808 file_count = 3;
4809 i = pipe_err = 0;
4810 while ((pipe_err == 0) && (i < file_count))
4811 pipe_err = pipe((int *)&p_fd[i++]);
4812 if (pipe_err < 0)
4813 {
4814 /* didn't get them all made - clean up and bail out */
4815 while (i-- > 0)
4816 {
4817 close(p_fd[i].wr);
4818 close(p_fd[i].rd);
4819 }
4820 errno = EPIPE;
4821 return posix_error();
4822 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004823
Victor Stinnerd6f85422010-05-05 23:33:33 +00004824 /* change the actual standard IO streams over temporarily,
4825 * making the retained pipe ends non-inheritable
4826 */
4827 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004828
Victor Stinnerd6f85422010-05-05 23:33:33 +00004829 /* - stdin */
4830 if (dup2(p_fd[0].rd, 0) == 0)
4831 {
4832 close(p_fd[0].rd);
4833 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4834 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4835 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4836 {
4837 close(p_fd[0].wr);
4838 pipe_err = -1;
4839 }
4840 }
4841 else
4842 {
4843 pipe_err = -1;
4844 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004845
Victor Stinnerd6f85422010-05-05 23:33:33 +00004846 /* - stdout */
4847 if (pipe_err == 0)
4848 {
4849 if (dup2(p_fd[1].wr, 1) == 1)
4850 {
4851 close(p_fd[1].wr);
4852 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4853 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4854 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4855 {
4856 close(p_fd[1].rd);
4857 pipe_err = -1;
4858 }
4859 }
4860 else
4861 {
4862 pipe_err = -1;
4863 }
4864 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004865
Victor Stinnerd6f85422010-05-05 23:33:33 +00004866 /* - stderr, as required */
4867 if (pipe_err == 0)
4868 switch (n)
4869 {
4870 case POPEN_3:
4871 {
4872 if (dup2(p_fd[2].wr, 2) == 2)
4873 {
4874 close(p_fd[2].wr);
4875 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4876 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4877 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4878 {
4879 close(p_fd[2].rd);
4880 pipe_err = -1;
4881 }
4882 }
4883 else
4884 {
4885 pipe_err = -1;
4886 }
4887 break;
4888 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004889
Victor Stinnerd6f85422010-05-05 23:33:33 +00004890 case POPEN_4:
4891 {
4892 if (dup2(1, 2) != 2)
4893 {
4894 pipe_err = -1;
4895 }
4896 break;
4897 }
4898 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004899
Victor Stinnerd6f85422010-05-05 23:33:33 +00004900 /* spawn the child process */
4901 if (pipe_err == 0)
4902 {
4903 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4904 if (pipe_pid == -1)
4905 {
4906 pipe_err = -1;
4907 }
4908 else
4909 {
4910 /* save the PID into the FILE structure
4911 * NOTE: this implementation doesn't actually
4912 * take advantage of this, but do it for
4913 * completeness - AIM Apr01
4914 */
4915 for (i = 0; i < file_count; i++)
4916 p_s[i]->_pid = pipe_pid;
4917 }
4918 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004919
Victor Stinnerd6f85422010-05-05 23:33:33 +00004920 /* reset standard IO to normal */
4921 for (i = 0; i < 3; i++)
4922 {
4923 dup2(stdio[i].handle, i);
4924 fcntl(i, F_SETFD, stdio[i].flags);
4925 close(stdio[i].handle);
4926 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004927
Victor Stinnerd6f85422010-05-05 23:33:33 +00004928 /* if any remnant problems, clean up and bail out */
4929 if (pipe_err < 0)
4930 {
4931 for (i = 0; i < 3; i++)
4932 {
4933 close(p_fd[i].rd);
4934 close(p_fd[i].wr);
4935 }
4936 errno = EPIPE;
4937 return posix_error_with_filename(cmdstring);
4938 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004939
Victor Stinnerd6f85422010-05-05 23:33:33 +00004940 /* build tuple of file objects to return */
4941 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4942 PyFile_SetBufSize(p_f[0], bufsize);
4943 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4944 PyFile_SetBufSize(p_f[1], bufsize);
4945 if (n == POPEN_3)
4946 {
4947 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4948 PyFile_SetBufSize(p_f[0], bufsize);
4949 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4950 }
4951 else
4952 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004953
Victor Stinnerd6f85422010-05-05 23:33:33 +00004954 /*
4955 * Insert the files we've created into the process dictionary
4956 * all referencing the list with the process handle and the
4957 * initial number of files (see description below in _PyPclose).
4958 * Since if _PyPclose later tried to wait on a process when all
4959 * handles weren't closed, it could create a deadlock with the
4960 * child, we spend some energy here to try to ensure that we
4961 * either insert all file handles into the dictionary or none
4962 * at all. It's a little clumsy with the various popen modes
4963 * and variable number of files involved.
4964 */
4965 if (!_PyPopenProcs)
4966 {
4967 _PyPopenProcs = PyDict_New();
4968 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004969
Victor Stinnerd6f85422010-05-05 23:33:33 +00004970 if (_PyPopenProcs)
4971 {
4972 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4973 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004974
Victor Stinnerd6f85422010-05-05 23:33:33 +00004975 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4976 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004977
Victor Stinnerd6f85422010-05-05 23:33:33 +00004978 procObj = PyList_New(2);
4979 pidObj = PyLong_FromPid(pipe_pid);
4980 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004981
Victor Stinnerd6f85422010-05-05 23:33:33 +00004982 if (procObj && pidObj && intObj)
4983 {
4984 PyList_SetItem(procObj, 0, pidObj);
4985 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004986
Victor Stinnerd6f85422010-05-05 23:33:33 +00004987 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4988 if (fileObj[0])
4989 {
4990 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4991 fileObj[0],
4992 procObj);
4993 }
4994 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4995 if (fileObj[1])
4996 {
4997 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4998 fileObj[1],
4999 procObj);
5000 }
5001 if (file_count >= 3)
5002 {
5003 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5004 if (fileObj[2])
5005 {
5006 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5007 fileObj[2],
5008 procObj);
5009 }
5010 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005011
Victor Stinnerd6f85422010-05-05 23:33:33 +00005012 if (ins_rc[0] < 0 || !fileObj[0] ||
5013 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5014 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5015 {
5016 /* Something failed - remove any dictionary
5017 * entries that did make it.
5018 */
5019 if (!ins_rc[0] && fileObj[0])
5020 {
5021 PyDict_DelItem(_PyPopenProcs,
5022 fileObj[0]);
5023 }
5024 if (!ins_rc[1] && fileObj[1])
5025 {
5026 PyDict_DelItem(_PyPopenProcs,
5027 fileObj[1]);
5028 }
5029 if (!ins_rc[2] && fileObj[2])
5030 {
5031 PyDict_DelItem(_PyPopenProcs,
5032 fileObj[2]);
5033 }
5034 }
5035 }
Tim Peters11b23062003-04-23 02:39:17 +00005036
Victor Stinnerd6f85422010-05-05 23:33:33 +00005037 /*
5038 * Clean up our localized references for the dictionary keys
5039 * and value since PyDict_SetItem will Py_INCREF any copies
5040 * that got placed in the dictionary.
5041 */
5042 Py_XDECREF(procObj);
5043 Py_XDECREF(fileObj[0]);
5044 Py_XDECREF(fileObj[1]);
5045 Py_XDECREF(fileObj[2]);
5046 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005047
Victor Stinnerd6f85422010-05-05 23:33:33 +00005048 /* Child is launched. */
5049 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005050}
5051
5052/*
5053 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5054 * exit code for the child process and return as a result of the close.
5055 *
5056 * This function uses the _PyPopenProcs dictionary in order to map the
5057 * input file pointer to information about the process that was
5058 * originally created by the popen* call that created the file pointer.
5059 * The dictionary uses the file pointer as a key (with one entry
5060 * inserted for each file returned by the original popen* call) and a
5061 * single list object as the value for all files from a single call.
5062 * The list object contains the Win32 process handle at [0], and a file
5063 * count at [1], which is initialized to the total number of file
5064 * handles using that list.
5065 *
5066 * This function closes whichever handle it is passed, and decrements
5067 * the file count in the dictionary for the process handle pointed to
5068 * by this file. On the last close (when the file count reaches zero),
5069 * this function will wait for the child process and then return its
5070 * exit code as the result of the close() operation. This permits the
5071 * files to be closed in any order - it is always the close() of the
5072 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005073 *
5074 * NOTE: This function is currently called with the GIL released.
5075 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005076 */
5077
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005078static int _PyPclose(FILE *file)
5079{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005080 int result;
5081 int exit_code;
5082 pid_t pipe_pid;
5083 PyObject *procObj, *pidObj, *intObj, *fileObj;
5084 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005085#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005086 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005087#endif
5088
Victor Stinnerd6f85422010-05-05 23:33:33 +00005089 /* Close the file handle first, to ensure it can't block the
5090 * child from exiting if it's the last handle.
5091 */
5092 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005093
5094#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005095 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005096#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005097 if (_PyPopenProcs)
5098 {
5099 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5100 (procObj = PyDict_GetItem(_PyPopenProcs,
5101 fileObj)) != NULL &&
5102 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5103 (intObj = PyList_GetItem(procObj,1)) != NULL)
5104 {
5105 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5106 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005107
Victor Stinnerd6f85422010-05-05 23:33:33 +00005108 if (file_count > 1)
5109 {
5110 /* Still other files referencing process */
5111 file_count--;
5112 PyList_SetItem(procObj,1,
5113 PyInt_FromLong((long) file_count));
5114 }
5115 else
5116 {
5117 /* Last file for this process */
5118 if (result != EOF &&
5119 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5120 {
5121 /* extract exit status */
5122 if (WIFEXITED(exit_code))
5123 {
5124 result = WEXITSTATUS(exit_code);
5125 }
5126 else
5127 {
5128 errno = EPIPE;
5129 result = -1;
5130 }
5131 }
5132 else
5133 {
5134 /* Indicate failure - this will cause the file object
5135 * to raise an I/O error and translate the last
5136 * error code from errno. We do have a problem with
5137 * last errors that overlap the normal errno table,
5138 * but that's a consistent problem with the file object.
5139 */
5140 result = -1;
5141 }
5142 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005143
Victor Stinnerd6f85422010-05-05 23:33:33 +00005144 /* Remove this file pointer from dictionary */
5145 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005146
Victor Stinnerd6f85422010-05-05 23:33:33 +00005147 if (PyDict_Size(_PyPopenProcs) == 0)
5148 {
5149 Py_DECREF(_PyPopenProcs);
5150 _PyPopenProcs = NULL;
5151 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005152
Victor Stinnerd6f85422010-05-05 23:33:33 +00005153 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005154
Victor Stinnerd6f85422010-05-05 23:33:33 +00005155 Py_XDECREF(fileObj);
5156 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005157
5158#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005159 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005161 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005162}
5163
5164#endif /* PYCC_??? */
5165
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005166#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005167
5168/*
5169 * Portable 'popen' replacement for Win32.
5170 *
5171 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5172 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005173 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005174 */
5175
5176#include <malloc.h>
5177#include <io.h>
5178#include <fcntl.h>
5179
5180/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5181#define POPEN_1 1
5182#define POPEN_2 2
5183#define POPEN_3 3
5184#define POPEN_4 4
5185
5186static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005187static int _PyPclose(FILE *file);
5188
5189/*
5190 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005191 * for use when retrieving the process exit code. See _PyPclose() below
5192 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005193 */
5194static PyObject *_PyPopenProcs = NULL;
5195
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005196
5197/* popen that works from a GUI.
5198 *
5199 * The result of this function is a pipe (file) connected to the
5200 * processes stdin or stdout, depending on the requested mode.
5201 */
5202
5203static PyObject *
5204posix_popen(PyObject *self, PyObject *args)
5205{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005206 PyObject *f;
5207 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005208
Victor Stinnerd6f85422010-05-05 23:33:33 +00005209 char *cmdstring;
5210 char *mode = "r";
5211 int bufsize = -1;
5212 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5213 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214
Victor Stinnerd6f85422010-05-05 23:33:33 +00005215 if (*mode == 'r')
5216 tm = _O_RDONLY;
5217 else if (*mode != 'w') {
5218 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5219 return NULL;
5220 } else
5221 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005222
Victor Stinnerd6f85422010-05-05 23:33:33 +00005223 if (bufsize != -1) {
5224 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5225 return NULL;
5226 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005227
Victor Stinnerd6f85422010-05-05 23:33:33 +00005228 if (*(mode+1) == 't')
5229 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5230 else if (*(mode+1) == 'b')
5231 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5232 else
5233 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005234
Victor Stinnerd6f85422010-05-05 23:33:33 +00005235 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236}
5237
5238/* Variation on win32pipe.popen
5239 *
5240 * The result of this function is a pipe (file) connected to the
5241 * process's stdin, and a pipe connected to the process's stdout.
5242 */
5243
5244static PyObject *
5245win32_popen2(PyObject *self, PyObject *args)
5246{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005247 PyObject *f;
5248 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005249
Victor Stinnerd6f85422010-05-05 23:33:33 +00005250 char *cmdstring;
5251 char *mode = "t";
5252 int bufsize = -1;
5253 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5254 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005255
Victor Stinnerd6f85422010-05-05 23:33:33 +00005256 if (*mode == 't')
5257 tm = _O_TEXT;
5258 else if (*mode != 'b') {
5259 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5260 return NULL;
5261 } else
5262 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Victor Stinnerd6f85422010-05-05 23:33:33 +00005264 if (bufsize != -1) {
5265 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5266 return NULL;
5267 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005268
Victor Stinnerd6f85422010-05-05 23:33:33 +00005269 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005270
Victor Stinnerd6f85422010-05-05 23:33:33 +00005271 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005272}
5273
5274/*
5275 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005276 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005277 * The result of this function is 3 pipes - the process's stdin,
5278 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005279 */
5280
5281static PyObject *
5282win32_popen3(PyObject *self, PyObject *args)
5283{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005284 PyObject *f;
5285 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005286
Victor Stinnerd6f85422010-05-05 23:33:33 +00005287 char *cmdstring;
5288 char *mode = "t";
5289 int bufsize = -1;
5290 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5291 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005292
Victor Stinnerd6f85422010-05-05 23:33:33 +00005293 if (*mode == 't')
5294 tm = _O_TEXT;
5295 else if (*mode != 'b') {
5296 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5297 return NULL;
5298 } else
5299 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005300
Victor Stinnerd6f85422010-05-05 23:33:33 +00005301 if (bufsize != -1) {
5302 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5303 return NULL;
5304 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005305
Victor Stinnerd6f85422010-05-05 23:33:33 +00005306 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005307
Victor Stinnerd6f85422010-05-05 23:33:33 +00005308 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005309}
5310
5311/*
5312 * Variation on win32pipe.popen
5313 *
Tim Peters5aa91602002-01-30 05:46:57 +00005314 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005315 * and stdout+stderr combined as a single pipe.
5316 */
5317
5318static PyObject *
5319win32_popen4(PyObject *self, PyObject *args)
5320{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005321 PyObject *f;
5322 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005323
Victor Stinnerd6f85422010-05-05 23:33:33 +00005324 char *cmdstring;
5325 char *mode = "t";
5326 int bufsize = -1;
5327 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5328 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005329
Victor Stinnerd6f85422010-05-05 23:33:33 +00005330 if (*mode == 't')
5331 tm = _O_TEXT;
5332 else if (*mode != 'b') {
5333 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5334 return NULL;
5335 } else
5336 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005337
Victor Stinnerd6f85422010-05-05 23:33:33 +00005338 if (bufsize != -1) {
5339 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5340 return NULL;
5341 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005342
Victor Stinnerd6f85422010-05-05 23:33:33 +00005343 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005344
Victor Stinnerd6f85422010-05-05 23:33:33 +00005345 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005346}
5347
Mark Hammond08501372001-01-31 07:30:29 +00005348static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005349_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005350 HANDLE hStdin,
5351 HANDLE hStdout,
5352 HANDLE hStderr,
5353 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005354{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005355 PROCESS_INFORMATION piProcInfo;
5356 STARTUPINFO siStartInfo;
5357 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5358 char *s1,*s2, *s3 = " /c ";
5359 const char *szConsoleSpawn = "w9xpopen.exe";
5360 int i;
5361 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005362
Victor Stinnerd6f85422010-05-05 23:33:33 +00005363 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5364 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005365
Victor Stinnerd6f85422010-05-05 23:33:33 +00005366 s1 = (char *)alloca(i);
5367 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5368 /* x < i, so x fits into an integer */
5369 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005370
Victor Stinnerd6f85422010-05-05 23:33:33 +00005371 /* Explicitly check if we are using COMMAND.COM. If we are
5372 * then use the w9xpopen hack.
5373 */
5374 comshell = s1 + x;
5375 while (comshell >= s1 && *comshell != '\\')
5376 --comshell;
5377 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005378
Victor Stinnerd6f85422010-05-05 23:33:33 +00005379 if (GetVersion() < 0x80000000 &&
5380 _stricmp(comshell, "command.com") != 0) {
5381 /* NT/2000 and not using command.com. */
5382 x = i + strlen(s3) + strlen(cmdstring) + 1;
5383 s2 = (char *)alloca(x);
5384 ZeroMemory(s2, x);
5385 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5386 }
5387 else {
5388 /*
5389 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5390 * the workaround listed in KB: Q150956
5391 */
5392 char modulepath[_MAX_PATH];
5393 struct stat statinfo;
5394 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5395 for (x = i = 0; modulepath[i]; i++)
5396 if (modulepath[i] == SEP)
5397 x = i+1;
5398 modulepath[x] = '\0';
5399 /* Create the full-name to w9xpopen, so we can test it exists */
5400 strncat(modulepath,
5401 szConsoleSpawn,
5402 (sizeof(modulepath)/sizeof(modulepath[0]))
5403 -strlen(modulepath));
5404 if (stat(modulepath, &statinfo) != 0) {
5405 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5406 /* Eeek - file-not-found - possibly an embedding
5407 situation - see if we can locate it in sys.prefix
5408 */
5409 strncpy(modulepath,
5410 Py_GetExecPrefix(),
5411 mplen);
5412 modulepath[mplen-1] = '\0';
5413 if (modulepath[strlen(modulepath)-1] != '\\')
5414 strcat(modulepath, "\\");
5415 strncat(modulepath,
5416 szConsoleSpawn,
5417 mplen-strlen(modulepath));
5418 /* No where else to look - raise an easily identifiable
5419 error, rather than leaving Windows to report
5420 "file not found" - as the user is probably blissfully
5421 unaware this shim EXE is used, and it will confuse them.
5422 (well, it confused me for a while ;-)
5423 */
5424 if (stat(modulepath, &statinfo) != 0) {
5425 PyErr_Format(PyExc_RuntimeError,
5426 "Can not locate '%s' which is needed "
5427 "for popen to work with your shell "
5428 "or platform.",
5429 szConsoleSpawn);
5430 return FALSE;
5431 }
5432 }
5433 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5434 strlen(modulepath) +
5435 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005436
Victor Stinnerd6f85422010-05-05 23:33:33 +00005437 s2 = (char *)alloca(x);
5438 ZeroMemory(s2, x);
5439 /* To maintain correct argument passing semantics,
5440 we pass the command-line as it stands, and allow
5441 quoting to be applied. w9xpopen.exe will then
5442 use its argv vector, and re-quote the necessary
5443 args for the ultimate child process.
5444 */
5445 PyOS_snprintf(
5446 s2, x,
5447 "\"%s\" %s%s%s",
5448 modulepath,
5449 s1,
5450 s3,
5451 cmdstring);
5452 /* Not passing CREATE_NEW_CONSOLE has been known to
5453 cause random failures on win9x. Specifically a
5454 dialog:
5455 "Your program accessed mem currently in use at xxx"
5456 and a hopeful warning about the stability of your
5457 system.
5458 Cost is Ctrl+C won't kill children, but anyone
5459 who cares can have a go!
5460 */
5461 dwProcessFlags |= CREATE_NEW_CONSOLE;
5462 }
5463 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005464
Victor Stinnerd6f85422010-05-05 23:33:33 +00005465 /* Could be an else here to try cmd.exe / command.com in the path
5466 Now we'll just error out.. */
5467 else {
5468 PyErr_SetString(PyExc_RuntimeError,
5469 "Cannot locate a COMSPEC environment variable to "
5470 "use as the shell");
5471 return FALSE;
5472 }
Tim Peters5aa91602002-01-30 05:46:57 +00005473
Victor Stinnerd6f85422010-05-05 23:33:33 +00005474 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5475 siStartInfo.cb = sizeof(STARTUPINFO);
5476 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5477 siStartInfo.hStdInput = hStdin;
5478 siStartInfo.hStdOutput = hStdout;
5479 siStartInfo.hStdError = hStderr;
5480 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005481
Victor Stinnerd6f85422010-05-05 23:33:33 +00005482 if (CreateProcess(NULL,
5483 s2,
5484 NULL,
5485 NULL,
5486 TRUE,
5487 dwProcessFlags,
5488 NULL,
5489 NULL,
5490 &siStartInfo,
5491 &piProcInfo) ) {
5492 /* Close the handles now so anyone waiting is woken. */
5493 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005494
Victor Stinnerd6f85422010-05-05 23:33:33 +00005495 /* Return process handle */
5496 *hProcess = piProcInfo.hProcess;
5497 return TRUE;
5498 }
5499 win32_error("CreateProcess", s2);
5500 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005501}
5502
5503/* The following code is based off of KB: Q190351 */
5504
5505static PyObject *
5506_PyPopen(char *cmdstring, int mode, int n)
5507{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005508 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5509 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5510 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005511
Victor Stinnerd6f85422010-05-05 23:33:33 +00005512 SECURITY_ATTRIBUTES saAttr;
5513 BOOL fSuccess;
5514 int fd1, fd2, fd3;
5515 FILE *f1, *f2, *f3;
5516 long file_count;
5517 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005518
Victor Stinnerd6f85422010-05-05 23:33:33 +00005519 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5520 saAttr.bInheritHandle = TRUE;
5521 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005522
Victor Stinnerd6f85422010-05-05 23:33:33 +00005523 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5524 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005525
Victor Stinnerd6f85422010-05-05 23:33:33 +00005526 /* Create new output read handle and the input write handle. Set
5527 * the inheritance properties to FALSE. Otherwise, the child inherits
5528 * these handles; resulting in non-closeable handles to the pipes
5529 * being created. */
5530 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5531 GetCurrentProcess(), &hChildStdinWrDup, 0,
5532 FALSE,
5533 DUPLICATE_SAME_ACCESS);
5534 if (!fSuccess)
5535 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005536
Victor Stinnerd6f85422010-05-05 23:33:33 +00005537 /* Close the inheritable version of ChildStdin
5538 that we're using. */
5539 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005540
Victor Stinnerd6f85422010-05-05 23:33:33 +00005541 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5542 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005543
Victor Stinnerd6f85422010-05-05 23:33:33 +00005544 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5545 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5546 FALSE, DUPLICATE_SAME_ACCESS);
5547 if (!fSuccess)
5548 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005549
Victor Stinnerd6f85422010-05-05 23:33:33 +00005550 /* Close the inheritable version of ChildStdout
5551 that we're using. */
5552 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005553
Victor Stinnerd6f85422010-05-05 23:33:33 +00005554 if (n != POPEN_4) {
5555 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5556 return win32_error("CreatePipe", NULL);
5557 fSuccess = DuplicateHandle(GetCurrentProcess(),
5558 hChildStderrRd,
5559 GetCurrentProcess(),
5560 &hChildStderrRdDup, 0,
5561 FALSE, DUPLICATE_SAME_ACCESS);
5562 if (!fSuccess)
5563 return win32_error("DuplicateHandle", NULL);
5564 /* Close the inheritable version of ChildStdErr that we're using. */
5565 CloseHandle(hChildStderrRd);
5566 }
Tim Peters5aa91602002-01-30 05:46:57 +00005567
Victor Stinnerd6f85422010-05-05 23:33:33 +00005568 switch (n) {
5569 case POPEN_1:
5570 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5571 case _O_WRONLY | _O_TEXT:
5572 /* Case for writing to child Stdin in text mode. */
5573 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5574 f1 = _fdopen(fd1, "w");
5575 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5576 PyFile_SetBufSize(f, 0);
5577 /* We don't care about these pipes anymore, so close them. */
5578 CloseHandle(hChildStdoutRdDup);
5579 CloseHandle(hChildStderrRdDup);
5580 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005581
Victor Stinnerd6f85422010-05-05 23:33:33 +00005582 case _O_RDONLY | _O_TEXT:
5583 /* Case for reading from child Stdout in text mode. */
5584 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5585 f1 = _fdopen(fd1, "r");
5586 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5587 PyFile_SetBufSize(f, 0);
5588 /* We don't care about these pipes anymore, so close them. */
5589 CloseHandle(hChildStdinWrDup);
5590 CloseHandle(hChildStderrRdDup);
5591 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005592
Victor Stinnerd6f85422010-05-05 23:33:33 +00005593 case _O_RDONLY | _O_BINARY:
5594 /* Case for readinig from child Stdout in binary mode. */
5595 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5596 f1 = _fdopen(fd1, "rb");
5597 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5598 PyFile_SetBufSize(f, 0);
5599 /* We don't care about these pipes anymore, so close them. */
5600 CloseHandle(hChildStdinWrDup);
5601 CloseHandle(hChildStderrRdDup);
5602 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005603
Victor Stinnerd6f85422010-05-05 23:33:33 +00005604 case _O_WRONLY | _O_BINARY:
5605 /* Case for writing to child Stdin in binary mode. */
5606 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5607 f1 = _fdopen(fd1, "wb");
5608 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5609 PyFile_SetBufSize(f, 0);
5610 /* We don't care about these pipes anymore, so close them. */
5611 CloseHandle(hChildStdoutRdDup);
5612 CloseHandle(hChildStderrRdDup);
5613 break;
5614 }
5615 file_count = 1;
5616 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005617
Victor Stinnerd6f85422010-05-05 23:33:33 +00005618 case POPEN_2:
5619 case POPEN_4:
5620 {
5621 char *m1, *m2;
5622 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005623
Victor Stinnerd6f85422010-05-05 23:33:33 +00005624 if (mode & _O_TEXT) {
5625 m1 = "r";
5626 m2 = "w";
5627 } else {
5628 m1 = "rb";
5629 m2 = "wb";
5630 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005631
Victor Stinnerd6f85422010-05-05 23:33:33 +00005632 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5633 f1 = _fdopen(fd1, m2);
5634 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5635 f2 = _fdopen(fd2, m1);
5636 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5637 PyFile_SetBufSize(p1, 0);
5638 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5639 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005640
Victor Stinnerd6f85422010-05-05 23:33:33 +00005641 if (n != 4)
5642 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005643
Victor Stinnerd6f85422010-05-05 23:33:33 +00005644 f = PyTuple_Pack(2,p1,p2);
5645 Py_XDECREF(p1);
5646 Py_XDECREF(p2);
5647 file_count = 2;
5648 break;
5649 }
Tim Peters5aa91602002-01-30 05:46:57 +00005650
Victor Stinnerd6f85422010-05-05 23:33:33 +00005651 case POPEN_3:
5652 {
5653 char *m1, *m2;
5654 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005655
Victor Stinnerd6f85422010-05-05 23:33:33 +00005656 if (mode & _O_TEXT) {
5657 m1 = "r";
5658 m2 = "w";
5659 } else {
5660 m1 = "rb";
5661 m2 = "wb";
5662 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005663
Victor Stinnerd6f85422010-05-05 23:33:33 +00005664 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5665 f1 = _fdopen(fd1, m2);
5666 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5667 f2 = _fdopen(fd2, m1);
5668 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5669 f3 = _fdopen(fd3, m1);
5670 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5671 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5672 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5673 PyFile_SetBufSize(p1, 0);
5674 PyFile_SetBufSize(p2, 0);
5675 PyFile_SetBufSize(p3, 0);
5676 f = PyTuple_Pack(3,p1,p2,p3);
5677 Py_XDECREF(p1);
5678 Py_XDECREF(p2);
5679 Py_XDECREF(p3);
5680 file_count = 3;
5681 break;
5682 }
5683 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005684
Victor Stinnerd6f85422010-05-05 23:33:33 +00005685 if (n == POPEN_4) {
5686 if (!_PyPopenCreateProcess(cmdstring,
5687 hChildStdinRd,
5688 hChildStdoutWr,
5689 hChildStdoutWr,
5690 &hProcess))
5691 return NULL;
5692 }
5693 else {
5694 if (!_PyPopenCreateProcess(cmdstring,
5695 hChildStdinRd,
5696 hChildStdoutWr,
5697 hChildStderrWr,
5698 &hProcess))
5699 return NULL;
5700 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005701
Victor Stinnerd6f85422010-05-05 23:33:33 +00005702 /*
5703 * Insert the files we've created into the process dictionary
5704 * all referencing the list with the process handle and the
5705 * initial number of files (see description below in _PyPclose).
5706 * Since if _PyPclose later tried to wait on a process when all
5707 * handles weren't closed, it could create a deadlock with the
5708 * child, we spend some energy here to try to ensure that we
5709 * either insert all file handles into the dictionary or none
5710 * at all. It's a little clumsy with the various popen modes
5711 * and variable number of files involved.
5712 */
5713 if (!_PyPopenProcs) {
5714 _PyPopenProcs = PyDict_New();
5715 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005716
Victor Stinnerd6f85422010-05-05 23:33:33 +00005717 if (_PyPopenProcs) {
5718 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5719 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005720
Victor Stinnerd6f85422010-05-05 23:33:33 +00005721 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5722 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005723
Victor Stinnerd6f85422010-05-05 23:33:33 +00005724 procObj = PyList_New(2);
5725 hProcessObj = PyLong_FromVoidPtr(hProcess);
5726 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005727
Victor Stinnerd6f85422010-05-05 23:33:33 +00005728 if (procObj && hProcessObj && intObj) {
5729 PyList_SetItem(procObj,0,hProcessObj);
5730 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005731
Victor Stinnerd6f85422010-05-05 23:33:33 +00005732 fileObj[0] = PyLong_FromVoidPtr(f1);
5733 if (fileObj[0]) {
5734 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5735 fileObj[0],
5736 procObj);
5737 }
5738 if (file_count >= 2) {
5739 fileObj[1] = PyLong_FromVoidPtr(f2);
5740 if (fileObj[1]) {
5741 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5742 fileObj[1],
5743 procObj);
5744 }
5745 }
5746 if (file_count >= 3) {
5747 fileObj[2] = PyLong_FromVoidPtr(f3);
5748 if (fileObj[2]) {
5749 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5750 fileObj[2],
5751 procObj);
5752 }
5753 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005754
Victor Stinnerd6f85422010-05-05 23:33:33 +00005755 if (ins_rc[0] < 0 || !fileObj[0] ||
5756 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5757 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5758 /* Something failed - remove any dictionary
5759 * entries that did make it.
5760 */
5761 if (!ins_rc[0] && fileObj[0]) {
5762 PyDict_DelItem(_PyPopenProcs,
5763 fileObj[0]);
5764 }
5765 if (!ins_rc[1] && fileObj[1]) {
5766 PyDict_DelItem(_PyPopenProcs,
5767 fileObj[1]);
5768 }
5769 if (!ins_rc[2] && fileObj[2]) {
5770 PyDict_DelItem(_PyPopenProcs,
5771 fileObj[2]);
5772 }
5773 }
5774 }
Tim Peters5aa91602002-01-30 05:46:57 +00005775
Victor Stinnerd6f85422010-05-05 23:33:33 +00005776 /*
5777 * Clean up our localized references for the dictionary keys
5778 * and value since PyDict_SetItem will Py_INCREF any copies
5779 * that got placed in the dictionary.
5780 */
5781 Py_XDECREF(procObj);
5782 Py_XDECREF(fileObj[0]);
5783 Py_XDECREF(fileObj[1]);
5784 Py_XDECREF(fileObj[2]);
5785 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005786
Victor Stinnerd6f85422010-05-05 23:33:33 +00005787 /* Child is launched. Close the parents copy of those pipe
5788 * handles that only the child should have open. You need to
5789 * make sure that no handles to the write end of the output pipe
5790 * are maintained in this process or else the pipe will not close
5791 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005792
Victor Stinnerd6f85422010-05-05 23:33:33 +00005793 if (!CloseHandle(hChildStdinRd))
5794 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005795
Victor Stinnerd6f85422010-05-05 23:33:33 +00005796 if (!CloseHandle(hChildStdoutWr))
5797 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005798
Victor Stinnerd6f85422010-05-05 23:33:33 +00005799 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5800 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005801
Victor Stinnerd6f85422010-05-05 23:33:33 +00005802 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005803}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005804
5805/*
5806 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5807 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005808 *
5809 * This function uses the _PyPopenProcs dictionary in order to map the
5810 * input file pointer to information about the process that was
5811 * originally created by the popen* call that created the file pointer.
5812 * The dictionary uses the file pointer as a key (with one entry
5813 * inserted for each file returned by the original popen* call) and a
5814 * single list object as the value for all files from a single call.
5815 * The list object contains the Win32 process handle at [0], and a file
5816 * count at [1], which is initialized to the total number of file
5817 * handles using that list.
5818 *
5819 * This function closes whichever handle it is passed, and decrements
5820 * the file count in the dictionary for the process handle pointed to
5821 * by this file. On the last close (when the file count reaches zero),
5822 * this function will wait for the child process and then return its
5823 * exit code as the result of the close() operation. This permits the
5824 * files to be closed in any order - it is always the close() of the
5825 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005826 *
5827 * NOTE: This function is currently called with the GIL released.
5828 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005829 */
Tim Peters736aa322000-09-01 06:51:24 +00005830
Fredrik Lundh56055a42000-07-23 19:47:12 +00005831static int _PyPclose(FILE *file)
5832{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005833 int result;
5834 DWORD exit_code;
5835 HANDLE hProcess;
5836 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5837 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005838#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005839 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005840#endif
5841
Victor Stinnerd6f85422010-05-05 23:33:33 +00005842 /* Close the file handle first, to ensure it can't block the
5843 * child from exiting if it's the last handle.
5844 */
5845 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005846#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005847 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005848#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005849 if (_PyPopenProcs) {
5850 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5851 (procObj = PyDict_GetItem(_PyPopenProcs,
5852 fileObj)) != NULL &&
5853 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5854 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005855
Victor Stinnerd6f85422010-05-05 23:33:33 +00005856 hProcess = PyLong_AsVoidPtr(hProcessObj);
5857 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005858
Victor Stinnerd6f85422010-05-05 23:33:33 +00005859 if (file_count > 1) {
5860 /* Still other files referencing process */
5861 file_count--;
5862 PyList_SetItem(procObj,1,
5863 PyInt_FromLong(file_count));
5864 } else {
5865 /* Last file for this process */
5866 if (result != EOF &&
5867 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5868 GetExitCodeProcess(hProcess, &exit_code)) {
5869 /* Possible truncation here in 16-bit environments, but
5870 * real exit codes are just the lower byte in any event.
5871 */
5872 result = exit_code;
5873 } else {
5874 /* Indicate failure - this will cause the file object
5875 * to raise an I/O error and translate the last Win32
5876 * error code from errno. We do have a problem with
5877 * last errors that overlap the normal errno table,
5878 * but that's a consistent problem with the file object.
5879 */
5880 if (result != EOF) {
5881 /* If the error wasn't from the fclose(), then
5882 * set errno for the file object error handling.
5883 */
5884 errno = GetLastError();
5885 }
5886 result = -1;
5887 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005888
Victor Stinnerd6f85422010-05-05 23:33:33 +00005889 /* Free up the native handle at this point */
5890 CloseHandle(hProcess);
5891 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005892
Victor Stinnerd6f85422010-05-05 23:33:33 +00005893 /* Remove this file pointer from dictionary */
5894 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005895
Victor Stinnerd6f85422010-05-05 23:33:33 +00005896 if (PyDict_Size(_PyPopenProcs) == 0) {
5897 Py_DECREF(_PyPopenProcs);
5898 _PyPopenProcs = NULL;
5899 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005900
Victor Stinnerd6f85422010-05-05 23:33:33 +00005901 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005902
Victor Stinnerd6f85422010-05-05 23:33:33 +00005903 Py_XDECREF(fileObj);
5904 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005905
Tim Peters736aa322000-09-01 06:51:24 +00005906#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005907 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005908#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005909 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005910}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005911
5912#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005914posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005915{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005916 char *name;
5917 char *mode = "r";
5918 int bufsize = -1;
5919 FILE *fp;
5920 PyObject *f;
5921 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5922 return NULL;
5923 /* Strip mode of binary or text modifiers */
5924 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5925 mode = "r";
5926 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5927 mode = "w";
5928 Py_BEGIN_ALLOW_THREADS
5929 fp = popen(name, mode);
5930 Py_END_ALLOW_THREADS
5931 if (fp == NULL)
5932 return posix_error();
5933 f = PyFile_FromFile(fp, name, mode, pclose);
5934 if (f != NULL)
5935 PyFile_SetBufSize(f, bufsize);
5936 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005937}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005938
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005939#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005940#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005941
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005942
Guido van Rossumb6775db1994-08-01 11:34:53 +00005943#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005944PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005945"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946Set the current process's user id.");
5947
Barry Warsaw53699e91996-12-10 23:23:01 +00005948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005949posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005950{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005951 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005952 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005953 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005954 if (setuid(uid) < 0)
5955 return posix_error();
5956 Py_INCREF(Py_None);
5957 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005958}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005959#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005961
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005962#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005964"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005965Set the current process's effective user id.");
5966
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005967static PyObject *
5968posix_seteuid (PyObject *self, PyObject *args)
5969{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005970 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005971 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005972 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005973 if (seteuid(euid) < 0) {
5974 return posix_error();
5975 } else {
5976 Py_INCREF(Py_None);
5977 return Py_None;
5978 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005979}
5980#endif /* HAVE_SETEUID */
5981
5982#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005984"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985Set the current process's effective group id.");
5986
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005987static PyObject *
5988posix_setegid (PyObject *self, PyObject *args)
5989{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005990 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005991 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005992 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005993 if (setegid(egid) < 0) {
5994 return posix_error();
5995 } else {
5996 Py_INCREF(Py_None);
5997 return Py_None;
5998 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005999}
6000#endif /* HAVE_SETEGID */
6001
6002#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006004"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006005Set the current process's real and effective user ids.");
6006
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006007static PyObject *
6008posix_setreuid (PyObject *self, PyObject *args)
6009{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006010 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006011 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6012 _Py_Uid_Converter, &ruid,
6013 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006014 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006015 if (setreuid(ruid, euid) < 0) {
6016 return posix_error();
6017 } else {
6018 Py_INCREF(Py_None);
6019 return Py_None;
6020 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006021}
6022#endif /* HAVE_SETREUID */
6023
6024#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006026"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006027Set the current process's real and effective group ids.");
6028
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006029static PyObject *
6030posix_setregid (PyObject *self, PyObject *args)
6031{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006032 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006033 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6034 _Py_Gid_Converter, &rgid,
6035 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006036 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006037 if (setregid(rgid, egid) < 0) {
6038 return posix_error();
6039 } else {
6040 Py_INCREF(Py_None);
6041 return Py_None;
6042 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006043}
6044#endif /* HAVE_SETREGID */
6045
Guido van Rossumb6775db1994-08-01 11:34:53 +00006046#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006048"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006050
Barry Warsaw53699e91996-12-10 23:23:01 +00006051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006052posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006053{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006054 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006055 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006056 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006057 if (setgid(gid) < 0)
6058 return posix_error();
6059 Py_INCREF(Py_None);
6060 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006061}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006062#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006063
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006064#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006066"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006068
6069static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006070posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006071{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006072 int i, len;
6073 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006074
Victor Stinnerd6f85422010-05-05 23:33:33 +00006075 if (!PySequence_Check(groups)) {
6076 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6077 return NULL;
6078 }
6079 len = PySequence_Size(groups);
6080 if (len > MAX_GROUPS) {
6081 PyErr_SetString(PyExc_ValueError, "too many groups");
6082 return NULL;
6083 }
6084 for(i = 0; i < len; i++) {
6085 PyObject *elem;
6086 elem = PySequence_GetItem(groups, i);
6087 if (!elem)
6088 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006089 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6090 PyErr_SetString(PyExc_TypeError,
6091 "groups must be integers");
6092 Py_DECREF(elem);
6093 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006094 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006095 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006096 Py_DECREF(elem);
6097 return NULL;
6098 }
6099 }
6100 Py_DECREF(elem);
6101 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006102
Victor Stinnerd6f85422010-05-05 23:33:33 +00006103 if (setgroups(len, grouplist) < 0)
6104 return posix_error();
6105 Py_INCREF(Py_None);
6106 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006107}
6108#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006109
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006110#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006111static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006112wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006113{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006114 PyObject *result;
6115 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006116
Victor Stinnerd6f85422010-05-05 23:33:33 +00006117 if (pid == -1)
6118 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006119
Victor Stinnerd6f85422010-05-05 23:33:33 +00006120 if (struct_rusage == NULL) {
6121 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6122 if (m == NULL)
6123 return NULL;
6124 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6125 Py_DECREF(m);
6126 if (struct_rusage == NULL)
6127 return NULL;
6128 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006129
Victor Stinnerd6f85422010-05-05 23:33:33 +00006130 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6131 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6132 if (!result)
6133 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006134
6135#ifndef doubletime
6136#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6137#endif
6138
Victor Stinnerd6f85422010-05-05 23:33:33 +00006139 PyStructSequence_SET_ITEM(result, 0,
6140 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6141 PyStructSequence_SET_ITEM(result, 1,
6142 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006143#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006144 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6145 SET_INT(result, 2, ru->ru_maxrss);
6146 SET_INT(result, 3, ru->ru_ixrss);
6147 SET_INT(result, 4, ru->ru_idrss);
6148 SET_INT(result, 5, ru->ru_isrss);
6149 SET_INT(result, 6, ru->ru_minflt);
6150 SET_INT(result, 7, ru->ru_majflt);
6151 SET_INT(result, 8, ru->ru_nswap);
6152 SET_INT(result, 9, ru->ru_inblock);
6153 SET_INT(result, 10, ru->ru_oublock);
6154 SET_INT(result, 11, ru->ru_msgsnd);
6155 SET_INT(result, 12, ru->ru_msgrcv);
6156 SET_INT(result, 13, ru->ru_nsignals);
6157 SET_INT(result, 14, ru->ru_nvcsw);
6158 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006159#undef SET_INT
6160
Victor Stinnerd6f85422010-05-05 23:33:33 +00006161 if (PyErr_Occurred()) {
6162 Py_DECREF(result);
6163 return NULL;
6164 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006165
Victor Stinnerd6f85422010-05-05 23:33:33 +00006166 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006167}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006168#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006169
6170#ifdef HAVE_WAIT3
6171PyDoc_STRVAR(posix_wait3__doc__,
6172"wait3(options) -> (pid, status, rusage)\n\n\
6173Wait for completion of a child process.");
6174
6175static PyObject *
6176posix_wait3(PyObject *self, PyObject *args)
6177{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006178 pid_t pid;
6179 int options;
6180 struct rusage ru;
6181 WAIT_TYPE status;
6182 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006183
Victor Stinnerd6f85422010-05-05 23:33:33 +00006184 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6185 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006186
Victor Stinnerd6f85422010-05-05 23:33:33 +00006187 Py_BEGIN_ALLOW_THREADS
6188 pid = wait3(&status, options, &ru);
6189 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006190
Victor Stinnerd6f85422010-05-05 23:33:33 +00006191 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006192}
6193#endif /* HAVE_WAIT3 */
6194
6195#ifdef HAVE_WAIT4
6196PyDoc_STRVAR(posix_wait4__doc__,
6197"wait4(pid, options) -> (pid, status, rusage)\n\n\
6198Wait for completion of a given child process.");
6199
6200static PyObject *
6201posix_wait4(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, PARSE_PID "i:wait4", &pid, &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 = wait4(pid, &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_WAIT4 */
6219
Guido van Rossumb6775db1994-08-01 11:34:53 +00006220#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006221PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006222"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006223Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006224
Barry Warsaw53699e91996-12-10 23:23:01 +00006225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006226posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006227{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006228 pid_t pid;
6229 int options;
6230 WAIT_TYPE status;
6231 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006232
Victor Stinnerd6f85422010-05-05 23:33:33 +00006233 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6234 return NULL;
6235 Py_BEGIN_ALLOW_THREADS
6236 pid = waitpid(pid, &status, options);
6237 Py_END_ALLOW_THREADS
6238 if (pid == -1)
6239 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006240
Victor Stinnerd6f85422010-05-05 23:33:33 +00006241 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006242}
6243
Tim Petersab034fa2002-02-01 11:27:43 +00006244#elif defined(HAVE_CWAIT)
6245
6246/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006247PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006248"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006249"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006250
6251static PyObject *
6252posix_waitpid(PyObject *self, PyObject *args)
6253{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006254 Py_intptr_t pid;
6255 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006256
Victor Stinnerd6f85422010-05-05 23:33:33 +00006257 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6258 return NULL;
6259 Py_BEGIN_ALLOW_THREADS
6260 pid = _cwait(&status, pid, options);
6261 Py_END_ALLOW_THREADS
6262 if (pid == -1)
6263 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006264
Victor Stinnerd6f85422010-05-05 23:33:33 +00006265 /* shift the status left a byte so this is more like the POSIX waitpid */
6266 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006267}
6268#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006269
Guido van Rossumad0ee831995-03-01 10:34:45 +00006270#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006272"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006273Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Barry Warsaw53699e91996-12-10 23:23:01 +00006275static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006276posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006278 pid_t pid;
6279 WAIT_TYPE status;
6280 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006281
Victor Stinnerd6f85422010-05-05 23:33:33 +00006282 Py_BEGIN_ALLOW_THREADS
6283 pid = wait(&status);
6284 Py_END_ALLOW_THREADS
6285 if (pid == -1)
6286 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006287
Victor Stinnerd6f85422010-05-05 23:33:33 +00006288 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006289}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006290#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006293PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006294"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006295Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006296
Barry Warsaw53699e91996-12-10 23:23:01 +00006297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006298posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006299{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006300#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006301 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006303#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006304 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006305#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006306 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006307#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006309}
6310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006311
Guido van Rossumb6775db1994-08-01 11:34:53 +00006312#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006314"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006316
Barry Warsaw53699e91996-12-10 23:23:01 +00006317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006318posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006319{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006320 PyObject* v;
6321 char buf[MAXPATHLEN];
6322 char *path;
6323 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006324#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006325 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006326#endif
6327
Victor Stinnerd6f85422010-05-05 23:33:33 +00006328 if (!PyArg_ParseTuple(args, "et:readlink",
6329 Py_FileSystemDefaultEncoding, &path))
6330 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006331#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006332 v = PySequence_GetItem(args, 0);
6333 if (v == NULL) {
6334 PyMem_Free(path);
6335 return NULL;
6336 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006337
Victor Stinnerd6f85422010-05-05 23:33:33 +00006338 if (PyUnicode_Check(v)) {
6339 arg_is_unicode = 1;
6340 }
6341 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006342#endif
6343
Victor Stinnerd6f85422010-05-05 23:33:33 +00006344 Py_BEGIN_ALLOW_THREADS
6345 n = readlink(path, buf, (int) sizeof buf);
6346 Py_END_ALLOW_THREADS
6347 if (n < 0)
6348 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006349
Victor Stinnerd6f85422010-05-05 23:33:33 +00006350 PyMem_Free(path);
6351 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006352#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006353 if (arg_is_unicode) {
6354 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006355
Victor Stinnerd6f85422010-05-05 23:33:33 +00006356 w = PyUnicode_FromEncodedObject(v,
6357 Py_FileSystemDefaultEncoding,
6358 "strict");
6359 if (w != NULL) {
6360 Py_DECREF(v);
6361 v = w;
6362 }
6363 else {
6364 /* fall back to the original byte string, as
6365 discussed in patch #683592 */
6366 PyErr_Clear();
6367 }
6368 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006369#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006370 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006371}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006372#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006374
Guido van Rossumb6775db1994-08-01 11:34:53 +00006375#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006376PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006377"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006378Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006379
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006381posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006382{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006383 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006384}
6385#endif /* HAVE_SYMLINK */
6386
6387
6388#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006389#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6390static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006391system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006392{
6393 ULONG value = 0;
6394
6395 Py_BEGIN_ALLOW_THREADS
6396 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6397 Py_END_ALLOW_THREADS
6398
6399 return value;
6400}
6401
6402static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006403posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006404{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006405 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006406 return Py_BuildValue("ddddd",
6407 (double)0 /* t.tms_utime / HZ */,
6408 (double)0 /* t.tms_stime / HZ */,
6409 (double)0 /* t.tms_cutime / HZ */,
6410 (double)0 /* t.tms_cstime / HZ */,
6411 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006412}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006413#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006414#define NEED_TICKS_PER_SECOND
6415static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006416static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006417posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006418{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006419 struct tms t;
6420 clock_t c;
6421 errno = 0;
6422 c = times(&t);
6423 if (c == (clock_t) -1)
6424 return posix_error();
6425 return Py_BuildValue("ddddd",
6426 (double)t.tms_utime / ticks_per_second,
6427 (double)t.tms_stime / ticks_per_second,
6428 (double)t.tms_cutime / ticks_per_second,
6429 (double)t.tms_cstime / ticks_per_second,
6430 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006431}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006432#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006433#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006434
6435
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006436#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006437#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006438static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006439posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006440{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006441 FILETIME create, exit, kernel, user;
6442 HANDLE hProc;
6443 hProc = GetCurrentProcess();
6444 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6445 /* The fields of a FILETIME structure are the hi and lo part
6446 of a 64-bit value expressed in 100 nanosecond units.
6447 1e7 is one second in such units; 1e-7 the inverse.
6448 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6449 */
6450 return Py_BuildValue(
6451 "ddddd",
6452 (double)(user.dwHighDateTime*429.4967296 +
6453 user.dwLowDateTime*1e-7),
6454 (double)(kernel.dwHighDateTime*429.4967296 +
6455 kernel.dwLowDateTime*1e-7),
6456 (double)0,
6457 (double)0,
6458 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006459}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006460#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006461
6462#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006463PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006464"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006465Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006466#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006468
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006469#ifdef HAVE_GETSID
6470PyDoc_STRVAR(posix_getsid__doc__,
6471"getsid(pid) -> sid\n\n\
6472Call the system call getsid().");
6473
6474static PyObject *
6475posix_getsid(PyObject *self, PyObject *args)
6476{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006477 pid_t pid;
6478 int sid;
6479 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6480 return NULL;
6481 sid = getsid(pid);
6482 if (sid < 0)
6483 return posix_error();
6484 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006485}
6486#endif /* HAVE_GETSID */
6487
6488
Guido van Rossumb6775db1994-08-01 11:34:53 +00006489#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006491"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Barry Warsaw53699e91996-12-10 23:23:01 +00006494static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006495posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006496{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006497 if (setsid() < 0)
6498 return posix_error();
6499 Py_INCREF(Py_None);
6500 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006501}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006502#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006503
Guido van Rossumb6775db1994-08-01 11:34:53 +00006504#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006505PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006506"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006508
Barry Warsaw53699e91996-12-10 23:23:01 +00006509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006510posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006512 pid_t pid;
6513 int pgrp;
6514 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6515 return NULL;
6516 if (setpgid(pid, pgrp) < 0)
6517 return posix_error();
6518 Py_INCREF(Py_None);
6519 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006520}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006521#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006523
Guido van Rossumb6775db1994-08-01 11:34:53 +00006524#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006526"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Barry Warsaw53699e91996-12-10 23:23:01 +00006529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006530posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006531{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006532 int fd;
6533 pid_t pgid;
6534 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6535 return NULL;
6536 pgid = tcgetpgrp(fd);
6537 if (pgid < 0)
6538 return posix_error();
6539 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006540}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006541#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006542
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006543
Guido van Rossumb6775db1994-08-01 11:34:53 +00006544#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006545PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006546"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006548
Barry Warsaw53699e91996-12-10 23:23:01 +00006549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006550posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006551{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006552 int fd;
6553 pid_t pgid;
6554 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6555 return NULL;
6556 if (tcsetpgrp(fd, pgid) < 0)
6557 return posix_error();
6558 Py_INCREF(Py_None);
6559 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006561#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006562
Guido van Rossum687dd131993-05-17 08:34:16 +00006563/* Functions acting on file descriptors */
6564
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006565PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006566"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006568
Barry Warsaw53699e91996-12-10 23:23:01 +00006569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006570posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006571{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006572 char *file = NULL;
6573 int flag;
6574 int mode = 0777;
6575 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006576
6577#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006578 PyUnicodeObject *po;
6579 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6580 Py_BEGIN_ALLOW_THREADS
6581 /* PyUnicode_AS_UNICODE OK without thread
6582 lock as it is a simple dereference. */
6583 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6584 Py_END_ALLOW_THREADS
6585 if (fd < 0)
6586 return posix_error();
6587 return PyInt_FromLong((long)fd);
6588 }
6589 /* Drop the argument parsing error as narrow strings
6590 are also valid. */
6591 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006592#endif
6593
Victor Stinnerd6f85422010-05-05 23:33:33 +00006594 if (!PyArg_ParseTuple(args, "eti|i",
6595 Py_FileSystemDefaultEncoding, &file,
6596 &flag, &mode))
6597 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006598
Victor Stinnerd6f85422010-05-05 23:33:33 +00006599 Py_BEGIN_ALLOW_THREADS
6600 fd = open(file, flag, mode);
6601 Py_END_ALLOW_THREADS
6602 if (fd < 0)
6603 return posix_error_with_allocated_filename(file);
6604 PyMem_Free(file);
6605 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006606}
6607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006609PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006610"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006611Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006612
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006613/*
6614The underscore at end of function name avoids a name clash with the libc
6615function posix_close.
6616*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006617static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006618posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006619{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006620 int fd, res;
6621 if (!PyArg_ParseTuple(args, "i:close", &fd))
6622 return NULL;
6623 if (!_PyVerify_fd(fd))
6624 return posix_error();
6625 Py_BEGIN_ALLOW_THREADS
6626 res = close(fd);
6627 Py_END_ALLOW_THREADS
6628 if (res < 0)
6629 return posix_error();
6630 Py_INCREF(Py_None);
6631 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006632}
6633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006634
Victor Stinnerd6f85422010-05-05 23:33:33 +00006635PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006636"closerange(fd_low, fd_high)\n\n\
6637Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6638
6639static PyObject *
6640posix_closerange(PyObject *self, PyObject *args)
6641{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006642 int fd_from, fd_to, i;
6643 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6644 return NULL;
6645 Py_BEGIN_ALLOW_THREADS
6646 for (i = fd_from; i < fd_to; i++)
6647 if (_PyVerify_fd(i))
6648 close(i);
6649 Py_END_ALLOW_THREADS
6650 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006651}
6652
6653
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006654PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006655"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006656Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006657
Barry Warsaw53699e91996-12-10 23:23:01 +00006658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006659posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006660{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006661 int fd;
6662 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6663 return NULL;
6664 if (!_PyVerify_fd(fd))
6665 return posix_error();
6666 Py_BEGIN_ALLOW_THREADS
6667 fd = dup(fd);
6668 Py_END_ALLOW_THREADS
6669 if (fd < 0)
6670 return posix_error();
6671 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006672}
6673
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006674
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006675PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006676"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006677Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006678
Barry Warsaw53699e91996-12-10 23:23:01 +00006679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006680posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006681{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006682 int fd, fd2, res;
6683 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6684 return NULL;
6685 if (!_PyVerify_fd_dup2(fd, fd2))
6686 return posix_error();
6687 Py_BEGIN_ALLOW_THREADS
6688 res = dup2(fd, fd2);
6689 Py_END_ALLOW_THREADS
6690 if (res < 0)
6691 return posix_error();
6692 Py_INCREF(Py_None);
6693 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006694}
6695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006696
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006697PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006698"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006699Set the current position of a file descriptor.\n\
6700Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006701
Barry Warsaw53699e91996-12-10 23:23:01 +00006702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006703posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006704{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006705 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006706#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006707 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006708#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006709 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006710#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006711 PyObject *posobj;
6712 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6713 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006714#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006715 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6716 switch (how) {
6717 case 0: how = SEEK_SET; break;
6718 case 1: how = SEEK_CUR; break;
6719 case 2: how = SEEK_END; break;
6720 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006721#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006722
6723#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006724 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006725#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006726 pos = PyLong_Check(posobj) ?
6727 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006728#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006729 if (PyErr_Occurred())
6730 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006731
Victor Stinnerd6f85422010-05-05 23:33:33 +00006732 if (!_PyVerify_fd(fd))
6733 return posix_error();
6734 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006735#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006736 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006737#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006738 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006739#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006740 Py_END_ALLOW_THREADS
6741 if (res < 0)
6742 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006743
6744#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006745 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006746#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006747 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006748#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006749}
6750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006751
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006752PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006753"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006754Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006755
Barry Warsaw53699e91996-12-10 23:23:01 +00006756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006757posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006758{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006759 int fd, size, n;
6760 PyObject *buffer;
6761 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6762 return NULL;
6763 if (size < 0) {
6764 errno = EINVAL;
6765 return posix_error();
6766 }
6767 buffer = PyString_FromStringAndSize((char *)NULL, size);
6768 if (buffer == NULL)
6769 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006770 if (!_PyVerify_fd(fd)) {
6771 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006772 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006773 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006774 Py_BEGIN_ALLOW_THREADS
6775 n = read(fd, PyString_AsString(buffer), size);
6776 Py_END_ALLOW_THREADS
6777 if (n < 0) {
6778 Py_DECREF(buffer);
6779 return posix_error();
6780 }
6781 if (n != size)
6782 _PyString_Resize(&buffer, n);
6783 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006784}
6785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006786
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006787PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006788"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006789Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006790
Barry Warsaw53699e91996-12-10 23:23:01 +00006791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006792posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006793{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006794 Py_buffer pbuf;
6795 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006796 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006797
Victor Stinnerd6f85422010-05-05 23:33:33 +00006798 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6799 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006800 if (!_PyVerify_fd(fd)) {
6801 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006802 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006803 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006804 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006805 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006806#if defined(MS_WIN64) || defined(MS_WINDOWS)
6807 if (len > INT_MAX)
6808 len = INT_MAX;
6809 size = write(fd, pbuf.buf, (int)len);
6810#else
6811 size = write(fd, pbuf.buf, len);
6812#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006813 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006814 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006815 if (size < 0)
6816 return posix_error();
6817 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006818}
6819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006821PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006822"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006823Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006824
Barry Warsaw53699e91996-12-10 23:23:01 +00006825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006826posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006827{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006828 int fd;
6829 STRUCT_STAT st;
6830 int res;
6831 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6832 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006833#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006834 /* on OpenVMS we must ensure that all bytes are written to the file */
6835 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006836#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006837 if (!_PyVerify_fd(fd))
6838 return posix_error();
6839 Py_BEGIN_ALLOW_THREADS
6840 res = FSTAT(fd, &st);
6841 Py_END_ALLOW_THREADS
6842 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006843#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006844 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006845#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006846 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006847#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006848 }
Tim Peters5aa91602002-01-30 05:46:57 +00006849
Victor Stinnerd6f85422010-05-05 23:33:33 +00006850 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006851}
6852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006855"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006857
Barry Warsaw53699e91996-12-10 23:23:01 +00006858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006859posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006860{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006861 int fd;
6862 char *orgmode = "r";
6863 int bufsize = -1;
6864 FILE *fp;
6865 PyObject *f;
6866 char *mode;
6867 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6868 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006869
Victor Stinnerd6f85422010-05-05 23:33:33 +00006870 /* Sanitize mode. See fileobject.c */
6871 mode = PyMem_MALLOC(strlen(orgmode)+3);
6872 if (!mode) {
6873 PyErr_NoMemory();
6874 return NULL;
6875 }
6876 strcpy(mode, orgmode);
6877 if (_PyFile_SanitizeMode(mode)) {
6878 PyMem_FREE(mode);
6879 return NULL;
6880 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006881 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006882 PyMem_FREE(mode);
6883 return posix_error();
6884 }
6885#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6886 {
6887 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006888 const char *msg;
6889 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006890 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6891 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006892 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006893 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006894 EISDIR, msg, "<fdopen>");
6895 if (exc) {
6896 PyErr_SetObject(PyExc_IOError, exc);
6897 Py_DECREF(exc);
6898 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006899 return NULL;
6900 }
6901 }
6902#endif
6903 /* The dummy filename used here must be kept in sync with the value
6904 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6905 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
6906 if (f == NULL) {
6907 PyMem_FREE(mode);
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006908 return NULL;
6909 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006910 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006911#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006912 if (mode[0] == 'a') {
6913 /* try to make sure the O_APPEND flag is set */
6914 int flags;
6915 flags = fcntl(fd, F_GETFL);
6916 if (flags != -1)
6917 fcntl(fd, F_SETFL, flags | O_APPEND);
6918 fp = fdopen(fd, mode);
6919 if (fp == NULL && flags != -1)
6920 /* restore old mode if fdopen failed */
6921 fcntl(fd, F_SETFL, flags);
6922 } else {
6923 fp = fdopen(fd, mode);
6924 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006925#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006926 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006927#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006928 Py_END_ALLOW_THREADS
6929 PyMem_FREE(mode);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006930 if (fp == NULL)
6931 return posix_error();
6932 /* We now know we will succeed, so initialize the file object. */
6933 ((PyFileObject *)f)->f_fp = fp;
6934 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006935 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006936}
6937
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006938PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006939"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006940Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006941connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006942
6943static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006944posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006945{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006946 int fd;
6947 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6948 return NULL;
6949 if (!_PyVerify_fd(fd))
6950 return PyBool_FromLong(0);
6951 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006952}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006953
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006954#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006956"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006957Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006958
Barry Warsaw53699e91996-12-10 23:23:01 +00006959static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006960posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006961{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006962#if defined(PYOS_OS2)
6963 HFILE read, write;
6964 APIRET rc;
6965
Victor Stinnerd6f85422010-05-05 23:33:33 +00006966 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006967 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006968 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006969 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006970 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006971
6972 return Py_BuildValue("(ii)", read, write);
6973#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006974#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006975 int fds[2];
6976 int res;
6977 Py_BEGIN_ALLOW_THREADS
6978 res = pipe(fds);
6979 Py_END_ALLOW_THREADS
6980 if (res != 0)
6981 return posix_error();
6982 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006983#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006984 HANDLE read, write;
6985 int read_fd, write_fd;
6986 BOOL ok;
6987 Py_BEGIN_ALLOW_THREADS
6988 ok = CreatePipe(&read, &write, NULL, 0);
6989 Py_END_ALLOW_THREADS
6990 if (!ok)
6991 return win32_error("CreatePipe", NULL);
6992 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6993 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6994 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006995#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006996#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006997}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006998#endif /* HAVE_PIPE */
6999
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007000
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007001#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007002PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007003"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007004Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007005
Barry Warsaw53699e91996-12-10 23:23:01 +00007006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007007posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007008{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007009 char *filename;
7010 int mode = 0666;
7011 int res;
7012 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7013 return NULL;
7014 Py_BEGIN_ALLOW_THREADS
7015 res = mkfifo(filename, mode);
7016 Py_END_ALLOW_THREADS
7017 if (res < 0)
7018 return posix_error();
7019 Py_INCREF(Py_None);
7020 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007021}
7022#endif
7023
7024
Neal Norwitz11690112002-07-30 01:08:28 +00007025#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007026PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007027"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007028Create a filesystem node (file, device special file or named pipe)\n\
7029named filename. mode specifies both the permissions to use and the\n\
7030type of node to be created, being combined (bitwise OR) with one of\n\
7031S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007032device defines the newly created device special file (probably using\n\
7033os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007034
7035
7036static PyObject *
7037posix_mknod(PyObject *self, PyObject *args)
7038{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007039 char *filename;
7040 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007041 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007042 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007043 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7044 &filename, &mode,
7045 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007046 return NULL;
7047 Py_BEGIN_ALLOW_THREADS
7048 res = mknod(filename, mode, device);
7049 Py_END_ALLOW_THREADS
7050 if (res < 0)
7051 return posix_error();
7052 Py_INCREF(Py_None);
7053 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007054}
7055#endif
7056
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007057#ifdef HAVE_DEVICE_MACROS
7058PyDoc_STRVAR(posix_major__doc__,
7059"major(device) -> major number\n\
7060Extracts a device major number from a raw device number.");
7061
7062static PyObject *
7063posix_major(PyObject *self, PyObject *args)
7064{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007065 dev_t device;
7066 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007067 return NULL;
7068 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007069}
7070
7071PyDoc_STRVAR(posix_minor__doc__,
7072"minor(device) -> minor number\n\
7073Extracts a device minor number from a raw device number.");
7074
7075static PyObject *
7076posix_minor(PyObject *self, PyObject *args)
7077{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007078 dev_t device;
7079 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007080 return NULL;
7081 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007082}
7083
7084PyDoc_STRVAR(posix_makedev__doc__,
7085"makedev(major, minor) -> device number\n\
7086Composes a raw device number from the major and minor device numbers.");
7087
7088static PyObject *
7089posix_makedev(PyObject *self, PyObject *args)
7090{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007091 int major, minor;
7092 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7093 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007094 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007095}
7096#endif /* device macros */
7097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007098
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007099#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007100PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007101"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007102Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007103
Barry Warsaw53699e91996-12-10 23:23:01 +00007104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007105posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007106{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007107 int fd;
7108 off_t length;
7109 int res;
7110 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007111
Victor Stinnerd6f85422010-05-05 23:33:33 +00007112 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7113 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007114
7115#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007116 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007117#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007118 length = PyLong_Check(lenobj) ?
7119 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007120#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007121 if (PyErr_Occurred())
7122 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007123
Victor Stinnerd6f85422010-05-05 23:33:33 +00007124 Py_BEGIN_ALLOW_THREADS
7125 res = ftruncate(fd, length);
7126 Py_END_ALLOW_THREADS
7127 if (res < 0)
7128 return posix_error();
7129 Py_INCREF(Py_None);
7130 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007131}
7132#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007133
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007134#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007135PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007136"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007137Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007138
Fred Drake762e2061999-08-26 17:23:54 +00007139/* Save putenv() parameters as values here, so we can collect them when they
7140 * get re-set with another call for the same key. */
7141static PyObject *posix_putenv_garbage;
7142
Tim Peters5aa91602002-01-30 05:46:57 +00007143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007144posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007145{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007146 char *s1, *s2;
7147 char *newenv;
7148 PyObject *newstr;
7149 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007150
Victor Stinnerd6f85422010-05-05 23:33:33 +00007151 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7152 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007153
7154#if defined(PYOS_OS2)
7155 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7156 APIRET rc;
7157
Guido van Rossumd48f2521997-12-05 22:19:34 +00007158 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7159 if (rc != NO_ERROR)
7160 return os2_error(rc);
7161
7162 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7163 APIRET rc;
7164
Guido van Rossumd48f2521997-12-05 22:19:34 +00007165 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7166 if (rc != NO_ERROR)
7167 return os2_error(rc);
7168 } else {
7169#endif
7170
Victor Stinnerd6f85422010-05-05 23:33:33 +00007171 /* XXX This can leak memory -- not easy to fix :-( */
7172 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007173#ifdef MS_WINDOWS
7174 if (_MAX_ENV < (len - 1)) {
7175 PyErr_Format(PyExc_ValueError,
7176 "the environment variable is longer than %u bytes",
7177 _MAX_ENV);
7178 return NULL;
7179 }
7180#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007181 /* len includes space for a trailing \0; the size arg to
7182 PyString_FromStringAndSize does not count that */
7183 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7184 if (newstr == NULL)
7185 return PyErr_NoMemory();
7186 newenv = PyString_AS_STRING(newstr);
7187 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7188 if (putenv(newenv)) {
7189 Py_DECREF(newstr);
7190 posix_error();
7191 return NULL;
7192 }
7193 /* Install the first arg and newstr in posix_putenv_garbage;
7194 * this will cause previous value to be collected. This has to
7195 * happen after the real putenv() call because the old value
7196 * was still accessible until then. */
7197 if (PyDict_SetItem(posix_putenv_garbage,
7198 PyTuple_GET_ITEM(args, 0), newstr)) {
7199 /* really not much we can do; just leak */
7200 PyErr_Clear();
7201 }
7202 else {
7203 Py_DECREF(newstr);
7204 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007205
7206#if defined(PYOS_OS2)
7207 }
7208#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007209 Py_INCREF(Py_None);
7210 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007211}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007212#endif /* putenv */
7213
Guido van Rossumc524d952001-10-19 01:31:59 +00007214#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007215PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007216"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007218
7219static PyObject *
7220posix_unsetenv(PyObject *self, PyObject *args)
7221{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007222 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007223#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007224 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007225#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007226
Victor Stinnerd6f85422010-05-05 23:33:33 +00007227 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7228 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007229
Charles-François Natali93a11752011-11-27 13:01:35 +01007230#ifdef HAVE_BROKEN_UNSETENV
7231 unsetenv(s1);
7232#else
Victor Stinner53853c32011-11-22 22:20:13 +01007233 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007234 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007235 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007236#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007237
Victor Stinnerd6f85422010-05-05 23:33:33 +00007238 /* Remove the key from posix_putenv_garbage;
7239 * this will cause it to be collected. This has to
7240 * happen after the real unsetenv() call because the
7241 * old value was still accessible until then.
7242 */
7243 if (PyDict_DelItem(posix_putenv_garbage,
7244 PyTuple_GET_ITEM(args, 0))) {
7245 /* really not much we can do; just leak */
7246 PyErr_Clear();
7247 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007248
Victor Stinnerd6f85422010-05-05 23:33:33 +00007249 Py_INCREF(Py_None);
7250 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007251}
7252#endif /* unsetenv */
7253
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007254PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007255"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007256Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007257
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007259posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007260{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007261 int code;
7262 char *message;
7263 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7264 return NULL;
7265 message = strerror(code);
7266 if (message == NULL) {
7267 PyErr_SetString(PyExc_ValueError,
7268 "strerror() argument out of range");
7269 return NULL;
7270 }
7271 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007272}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007273
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007274
Guido van Rossumc9641791998-08-04 15:26:23 +00007275#ifdef HAVE_SYS_WAIT_H
7276
Fred Drake106c1a02002-04-23 15:58:02 +00007277#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007278PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007279"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007280Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007281
7282static PyObject *
7283posix_WCOREDUMP(PyObject *self, PyObject *args)
7284{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007285 WAIT_TYPE status;
7286 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007287
Victor Stinnerd6f85422010-05-05 23:33:33 +00007288 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7289 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007290
Victor Stinnerd6f85422010-05-05 23:33:33 +00007291 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007292}
7293#endif /* WCOREDUMP */
7294
7295#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007296PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007297"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007298Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007299job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007300
7301static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007302posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007303{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007304 WAIT_TYPE status;
7305 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007306
Victor Stinnerd6f85422010-05-05 23:33:33 +00007307 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7308 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007309
Victor Stinnerd6f85422010-05-05 23:33:33 +00007310 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007311}
7312#endif /* WIFCONTINUED */
7313
Guido van Rossumc9641791998-08-04 15:26:23 +00007314#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007315PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007316"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007317Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007318
7319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007320posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007321{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007322 WAIT_TYPE status;
7323 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007324
Victor Stinnerd6f85422010-05-05 23:33:33 +00007325 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7326 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007327
Victor Stinnerd6f85422010-05-05 23:33:33 +00007328 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007329}
7330#endif /* WIFSTOPPED */
7331
7332#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007333PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007334"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007335Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007336
7337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007338posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007339{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007340 WAIT_TYPE status;
7341 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007342
Victor Stinnerd6f85422010-05-05 23:33:33 +00007343 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7344 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007345
Victor Stinnerd6f85422010-05-05 23:33:33 +00007346 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007347}
7348#endif /* WIFSIGNALED */
7349
7350#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007351PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007352"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007353Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007354system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007355
7356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007357posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007358{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007359 WAIT_TYPE status;
7360 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007361
Victor Stinnerd6f85422010-05-05 23:33:33 +00007362 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7363 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007364
Victor Stinnerd6f85422010-05-05 23:33:33 +00007365 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007366}
7367#endif /* WIFEXITED */
7368
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007369#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007370PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007371"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007372Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007373
7374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007375posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007376{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007377 WAIT_TYPE status;
7378 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007379
Victor Stinnerd6f85422010-05-05 23:33:33 +00007380 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7381 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007382
Victor Stinnerd6f85422010-05-05 23:33:33 +00007383 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007384}
7385#endif /* WEXITSTATUS */
7386
7387#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007388PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007389"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007390Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007391value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007392
7393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007394posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007395{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007396 WAIT_TYPE status;
7397 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007398
Victor Stinnerd6f85422010-05-05 23:33:33 +00007399 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7400 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007401
Victor Stinnerd6f85422010-05-05 23:33:33 +00007402 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007403}
7404#endif /* WTERMSIG */
7405
7406#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007407PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007408"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007409Return the signal that stopped the process that provided\n\
7410the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007411
7412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007413posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007414{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007415 WAIT_TYPE status;
7416 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007417
Victor Stinnerd6f85422010-05-05 23:33:33 +00007418 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7419 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007420
Victor Stinnerd6f85422010-05-05 23:33:33 +00007421 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007422}
7423#endif /* WSTOPSIG */
7424
7425#endif /* HAVE_SYS_WAIT_H */
7426
7427
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007428#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007429#ifdef _SCO_DS
7430/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7431 needed definitions in sys/statvfs.h */
7432#define _SVID3
7433#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007434#include <sys/statvfs.h>
7435
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007436static PyObject*
7437_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007438 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7439 if (v == NULL)
7440 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007441
7442#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007443 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7444 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7445 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7446 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7447 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7448 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7449 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7450 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7451 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7452 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007453#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007454 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7455 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7456 PyStructSequence_SET_ITEM(v, 2,
7457 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7458 PyStructSequence_SET_ITEM(v, 3,
7459 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7460 PyStructSequence_SET_ITEM(v, 4,
7461 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7462 PyStructSequence_SET_ITEM(v, 5,
7463 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7464 PyStructSequence_SET_ITEM(v, 6,
7465 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7466 PyStructSequence_SET_ITEM(v, 7,
7467 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7468 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7469 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007470#endif
7471
Victor Stinnerd6f85422010-05-05 23:33:33 +00007472 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007473}
7474
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007475PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007476"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007477Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007478
7479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007480posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007481{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007482 int fd, res;
7483 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007484
Victor Stinnerd6f85422010-05-05 23:33:33 +00007485 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7486 return NULL;
7487 Py_BEGIN_ALLOW_THREADS
7488 res = fstatvfs(fd, &st);
7489 Py_END_ALLOW_THREADS
7490 if (res != 0)
7491 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007492
Victor Stinnerd6f85422010-05-05 23:33:33 +00007493 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007494}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007495#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007496
7497
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007498#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007499#include <sys/statvfs.h>
7500
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007501PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007502"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007503Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007504
7505static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007506posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007507{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007508 char *path;
7509 int res;
7510 struct statvfs st;
7511 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7512 return NULL;
7513 Py_BEGIN_ALLOW_THREADS
7514 res = statvfs(path, &st);
7515 Py_END_ALLOW_THREADS
7516 if (res != 0)
7517 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007518
Victor Stinnerd6f85422010-05-05 23:33:33 +00007519 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007520}
7521#endif /* HAVE_STATVFS */
7522
7523
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007524#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007525PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007526"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007527Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007528The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007529or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007530
7531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007532posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007533{
7534 PyObject *result = NULL;
7535 char *dir = NULL;
7536 char *pfx = NULL;
7537 char *name;
7538
7539 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007540 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007541
7542 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007543 "tempnam is a potential security risk to your program") < 0)
7544 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007545
Antoine Pitroub0614612011-01-02 20:04:52 +00007546 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7547 "use the tempfile module", 1) < 0)
7548 return NULL;
7549
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007550#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007551 name = _tempnam(dir, pfx);
7552#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007553 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007554#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007556 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007557 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007558 free(name);
7559 return result;
7560}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007561#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007562
7563
7564#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007565PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007566"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007567Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007568
7569static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007570posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007571{
7572 FILE *fp;
7573
Antoine Pitroub0614612011-01-02 20:04:52 +00007574 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7575 "use the tempfile module", 1) < 0)
7576 return NULL;
7577
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007578 fp = tmpfile();
7579 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007580 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007581 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007582}
7583#endif
7584
7585
7586#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007587PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007588"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007589Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007590
7591static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007592posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007593{
7594 char buffer[L_tmpnam];
7595 char *name;
7596
Skip Montanaro95618b52001-08-18 18:52:10 +00007597 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007598 "tmpnam is a potential security risk to your program") < 0)
7599 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007600
Antoine Pitroub0614612011-01-02 20:04:52 +00007601 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7602 "use the tempfile module", 1) < 0)
7603 return NULL;
7604
Greg Wardb48bc172000-03-01 21:51:56 +00007605#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007606 name = tmpnam_r(buffer);
7607#else
7608 name = tmpnam(buffer);
7609#endif
7610 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007611 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007612#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007613 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007614#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007615 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007616#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007617 );
7618 PyErr_SetObject(PyExc_OSError, err);
7619 Py_XDECREF(err);
7620 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007621 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007622 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623}
7624#endif
7625
7626
Fred Drakec9680921999-12-13 16:37:25 +00007627/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7628 * It maps strings representing configuration variable names to
7629 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007630 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007631 * rarely-used constants. There are three separate tables that use
7632 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007633 *
7634 * This code is always included, even if none of the interfaces that
7635 * need it are included. The #if hackery needed to avoid it would be
7636 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007637 */
7638struct constdef {
7639 char *name;
7640 long value;
7641};
7642
Fred Drake12c6e2d1999-12-14 21:25:03 +00007643static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007644conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007645 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007646{
7647 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007648 *valuep = PyInt_AS_LONG(arg);
7649 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007650 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007651 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007652 /* look up the value in the table using a binary search */
7653 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007654 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007655 size_t hi = tablesize;
7656 int cmp;
7657 char *confname = PyString_AS_STRING(arg);
7658 while (lo < hi) {
7659 mid = (lo + hi) / 2;
7660 cmp = strcmp(confname, table[mid].name);
7661 if (cmp < 0)
7662 hi = mid;
7663 else if (cmp > 0)
7664 lo = mid + 1;
7665 else {
7666 *valuep = table[mid].value;
7667 return 1;
7668 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007669 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007670 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007671 }
7672 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007673 PyErr_SetString(PyExc_TypeError,
7674 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007675 return 0;
7676}
7677
7678
7679#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7680static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007681#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007682 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007683#endif
7684#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007685 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007686#endif
Fred Drakec9680921999-12-13 16:37:25 +00007687#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007688 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007689#endif
7690#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007691 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007692#endif
7693#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007694 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007695#endif
7696#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007697 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007698#endif
7699#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007700 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007701#endif
7702#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007703 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007704#endif
7705#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007706 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007707#endif
7708#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007709 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007710#endif
7711#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007712 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007713#endif
7714#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007715 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007716#endif
7717#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007718 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007719#endif
7720#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007721 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007722#endif
7723#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007724 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007725#endif
7726#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007727 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007728#endif
7729#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007730 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007731#endif
7732};
7733
Fred Drakec9680921999-12-13 16:37:25 +00007734static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007735conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007736{
7737 return conv_confname(arg, valuep, posix_constants_pathconf,
7738 sizeof(posix_constants_pathconf)
7739 / sizeof(struct constdef));
7740}
7741#endif
7742
7743#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007744PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007745"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007746Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007747If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007748
7749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007750posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007751{
7752 PyObject *result = NULL;
7753 int name, fd;
7754
Fred Drake12c6e2d1999-12-14 21:25:03 +00007755 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7756 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007757 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007758
Stefan Krah93f7a322010-11-26 17:35:50 +00007759 errno = 0;
7760 limit = fpathconf(fd, name);
7761 if (limit == -1 && errno != 0)
7762 posix_error();
7763 else
7764 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007765 }
7766 return result;
7767}
7768#endif
7769
7770
7771#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007772PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007773"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007774Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007775If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007776
7777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007778posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007779{
7780 PyObject *result = NULL;
7781 int name;
7782 char *path;
7783
7784 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7785 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007786 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007787
Victor Stinnerd6f85422010-05-05 23:33:33 +00007788 errno = 0;
7789 limit = pathconf(path, name);
7790 if (limit == -1 && errno != 0) {
7791 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007792 /* could be a path or name problem */
7793 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007794 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007795 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007796 }
7797 else
7798 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007799 }
7800 return result;
7801}
7802#endif
7803
7804#ifdef HAVE_CONFSTR
7805static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007806#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007807 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007808#endif
7809#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007810 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007811#endif
7812#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007814#endif
7815#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007816 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007817#endif
7818#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007819 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007820#endif
Fred Drakec9680921999-12-13 16:37:25 +00007821#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007822 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007823#endif
7824#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007825 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007826#endif
7827#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007828 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007829#endif
7830#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007831 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007832#endif
7833#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007834 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007835#endif
7836#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007837 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007838#endif
7839#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007840 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007841#endif
7842#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007843 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007844#endif
Fred Draked86ed291999-12-15 15:34:33 +00007845#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007846 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007847#endif
Fred Drakec9680921999-12-13 16:37:25 +00007848#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007850#endif
Fred Draked86ed291999-12-15 15:34:33 +00007851#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007853#endif
7854#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007856#endif
7857#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007859#endif
7860#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007862#endif
Fred Drakec9680921999-12-13 16:37:25 +00007863#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007865#endif
7866#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
7869#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
7881#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007883#endif
7884#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007886#endif
7887#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007889#endif
7890#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007892#endif
7893#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007895#endif
7896#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007898#endif
7899#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007901#endif
7902#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007904#endif
7905#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
7908#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007910#endif
Fred Draked86ed291999-12-15 15:34:33 +00007911#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007913#endif
7914#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007916#endif
7917#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007919#endif
7920#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007922#endif
7923#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007925#endif
7926#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007928#endif
7929#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007931#endif
7932#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007934#endif
7935#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007937#endif
7938#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007940#endif
7941#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007943#endif
7944#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007946#endif
7947#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007949#endif
Fred Drakec9680921999-12-13 16:37:25 +00007950};
7951
7952static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007953conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007954{
7955 return conv_confname(arg, valuep, posix_constants_confstr,
7956 sizeof(posix_constants_confstr)
7957 / sizeof(struct constdef));
7958}
7959
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007960PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007961"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007962Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007963
7964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007965posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007966{
7967 PyObject *result = NULL;
7968 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007969 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007970
7971 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007973
Victor Stinnerd6f85422010-05-05 23:33:33 +00007974 errno = 0;
7975 len = confstr(name, buffer, sizeof(buffer));
7976 if (len == 0) {
7977 if (errno) {
7978 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007979 }
7980 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 result = Py_None;
7982 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007983 }
7984 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007985 else {
7986 if ((unsigned int)len >= sizeof(buffer)) {
7987 result = PyString_FromStringAndSize(NULL, len-1);
7988 if (result != NULL)
7989 confstr(name, PyString_AS_STRING(result), len);
7990 }
7991 else
7992 result = PyString_FromStringAndSize(buffer, len-1);
7993 }
7994 }
Fred Drakec9680921999-12-13 16:37:25 +00007995 return result;
7996}
7997#endif
7998
7999
8000#ifdef HAVE_SYSCONF
8001static struct constdef posix_constants_sysconf[] = {
8002#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008003 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008004#endif
8005#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008006 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008007#endif
8008#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008009 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008010#endif
8011#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008012 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008013#endif
8014#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008015 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008016#endif
8017#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008018 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008019#endif
8020#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008021 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008022#endif
8023#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008024 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008025#endif
8026#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008027 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008028#endif
8029#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008030 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008031#endif
Fred Draked86ed291999-12-15 15:34:33 +00008032#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008033 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008034#endif
8035#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008036 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008037#endif
Fred Drakec9680921999-12-13 16:37:25 +00008038#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008039 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008040#endif
Fred Drakec9680921999-12-13 16:37:25 +00008041#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008042 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008043#endif
8044#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008045 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008046#endif
8047#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008048 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008049#endif
8050#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008051 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008052#endif
8053#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008054 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008055#endif
Fred Draked86ed291999-12-15 15:34:33 +00008056#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008057 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008058#endif
Fred Drakec9680921999-12-13 16:37:25 +00008059#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008060 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008061#endif
8062#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008063 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008064#endif
8065#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008066 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008067#endif
8068#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008069 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008070#endif
8071#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008072 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008073#endif
Fred Draked86ed291999-12-15 15:34:33 +00008074#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008075 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008076#endif
Fred Drakec9680921999-12-13 16:37:25 +00008077#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008078 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008079#endif
8080#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008081 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008082#endif
8083#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008084 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008085#endif
8086#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008087 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008088#endif
8089#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008090 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008091#endif
8092#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008093 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008094#endif
8095#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008096 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008097#endif
8098#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008099 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008100#endif
8101#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008102 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008103#endif
8104#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008105 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008106#endif
8107#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008108 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008109#endif
8110#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008111 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008112#endif
8113#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008114 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008115#endif
8116#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008117 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008118#endif
8119#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008120 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008121#endif
8122#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008123 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008124#endif
8125#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008126 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008127#endif
8128#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008129 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008130#endif
8131#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008132 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008133#endif
8134#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008135 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008136#endif
8137#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008138 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008139#endif
8140#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008141 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008142#endif
8143#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008144 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008145#endif
Fred Draked86ed291999-12-15 15:34:33 +00008146#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008147 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008148#endif
Fred Drakec9680921999-12-13 16:37:25 +00008149#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008150 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008151#endif
8152#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008153 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008154#endif
8155#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008156 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008157#endif
Fred Draked86ed291999-12-15 15:34:33 +00008158#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008159 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008160#endif
Fred Drakec9680921999-12-13 16:37:25 +00008161#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008162 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008163#endif
Fred Draked86ed291999-12-15 15:34:33 +00008164#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008165 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008166#endif
8167#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008168 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008169#endif
Fred Drakec9680921999-12-13 16:37:25 +00008170#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008171 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008172#endif
8173#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008174 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008175#endif
8176#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008177 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008178#endif
8179#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008180 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008181#endif
Fred Draked86ed291999-12-15 15:34:33 +00008182#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008183 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008184#endif
Fred Drakec9680921999-12-13 16:37:25 +00008185#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008186 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008187#endif
8188#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008189 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008190#endif
8191#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008192 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008193#endif
8194#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008195 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008196#endif
8197#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008198 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008199#endif
8200#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008201 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008202#endif
8203#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008204 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008205#endif
Fred Draked86ed291999-12-15 15:34:33 +00008206#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008207 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008208#endif
Fred Drakec9680921999-12-13 16:37:25 +00008209#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008210 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008211#endif
8212#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008213 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008214#endif
Fred Draked86ed291999-12-15 15:34:33 +00008215#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008216 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008217#endif
Fred Drakec9680921999-12-13 16:37:25 +00008218#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008219 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008220#endif
8221#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008222 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008223#endif
8224#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008225 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008226#endif
8227#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008228 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008229#endif
8230#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008231 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008232#endif
8233#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008234 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008235#endif
8236#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008237 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008238#endif
8239#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008240 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008241#endif
8242#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008243 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008244#endif
Fred Draked86ed291999-12-15 15:34:33 +00008245#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008246 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008247#endif
8248#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008249 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008250#endif
Fred Drakec9680921999-12-13 16:37:25 +00008251#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008252 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008253#endif
8254#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008255 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
8257#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008258 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008259#endif
8260#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008261 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008264 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008267 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
8269#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008270 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008271#endif
8272#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008273 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008274#endif
8275#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008276 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008277#endif
8278#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008279 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
8281#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008282 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008283#endif
8284#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008285 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008286#endif
8287#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008288 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008289#endif
8290#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008291 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008292#endif
8293#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008294 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008295#endif
8296#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008297 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008298#endif
8299#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008300 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008301#endif
8302#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008303 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008304#endif
8305#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008306 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008307#endif
8308#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008309 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008310#endif
8311#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008312 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008313#endif
8314#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008315 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008316#endif
8317#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008318 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008319#endif
8320#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008321 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008322#endif
8323#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008324 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008325#endif
8326#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008327 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008328#endif
8329#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008330 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008331#endif
8332#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008333 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008334#endif
8335#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008336 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008337#endif
8338#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008339 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008340#endif
8341#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008342 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008343#endif
8344#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008345 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008346#endif
8347#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008348 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008349#endif
8350#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008351 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008352#endif
8353#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008354 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008355#endif
Fred Draked86ed291999-12-15 15:34:33 +00008356#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008357 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008358#endif
Fred Drakec9680921999-12-13 16:37:25 +00008359#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008360 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008361#endif
8362#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008363 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008364#endif
8365#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008366 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008367#endif
8368#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008369 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008370#endif
8371#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008372 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008373#endif
8374#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008375 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008376#endif
8377#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008378 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008379#endif
8380#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008381 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008382#endif
8383#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008384 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008385#endif
8386#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008387 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008388#endif
8389#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008390 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008391#endif
8392#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008393 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008394#endif
8395#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008396 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008397#endif
8398#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008399 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008400#endif
8401#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008402 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008403#endif
8404#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008405 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008406#endif
8407#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008408 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008409#endif
8410#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008411 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008412#endif
8413#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008414 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008415#endif
8416#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008417 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008418#endif
8419#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008420 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008421#endif
8422#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008423 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008424#endif
8425#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008426 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008427#endif
8428#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008429 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008430#endif
8431#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008432 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008433#endif
8434#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008435 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008436#endif
8437#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008438 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008439#endif
8440#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008441 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008442#endif
8443#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008444 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008445#endif
8446#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008447 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008448#endif
8449#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008450 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008451#endif
8452#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008453 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008454#endif
8455#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008456 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008457#endif
8458#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008459 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008460#endif
8461#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008462 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008463#endif
8464#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008465 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008466#endif
8467#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008469#endif
8470#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008471 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008472#endif
8473#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008474 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008475#endif
8476#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008477 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008478#endif
8479#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008480 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008481#endif
8482#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008483 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008484#endif
8485#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008486 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008487#endif
8488#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008489 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008490#endif
8491#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008492 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008493#endif
8494};
8495
8496static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008497conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008498{
8499 return conv_confname(arg, valuep, posix_constants_sysconf,
8500 sizeof(posix_constants_sysconf)
8501 / sizeof(struct constdef));
8502}
8503
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008504PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008505"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008506Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008507
8508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008509posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008510{
8511 PyObject *result = NULL;
8512 int name;
8513
8514 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008515 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008516
Victor Stinner862490a2010-05-06 00:03:44 +00008517 errno = 0;
8518 value = sysconf(name);
8519 if (value == -1 && errno != 0)
8520 posix_error();
8521 else
8522 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008523 }
8524 return result;
8525}
8526#endif
8527
8528
Fred Drakebec628d1999-12-15 18:31:10 +00008529/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008530 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008531 * the exported dictionaries that are used to publish information about the
8532 * names available on the host platform.
8533 *
8534 * Sorting the table at runtime ensures that the table is properly ordered
8535 * when used, even for platforms we're not able to test on. It also makes
8536 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008537 */
Fred Drakebec628d1999-12-15 18:31:10 +00008538
8539static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008540cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008541{
8542 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008543 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008544 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008545 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008546
8547 return strcmp(c1->name, c2->name);
8548}
8549
8550static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008551setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008552 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008553{
Fred Drakebec628d1999-12-15 18:31:10 +00008554 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008555 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008556 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8557 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008558 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008559 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008560
Barry Warsaw3155db32000-04-13 15:20:40 +00008561 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008562 PyObject *o = PyInt_FromLong(table[i].value);
8563 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8564 Py_XDECREF(o);
8565 Py_DECREF(d);
8566 return -1;
8567 }
8568 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008569 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008570 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008571}
8572
Fred Drakebec628d1999-12-15 18:31:10 +00008573/* Return -1 on failure, 0 on success. */
8574static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008575setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008576{
8577#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008578 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008579 sizeof(posix_constants_pathconf)
8580 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008581 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008582 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008583#endif
8584#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008585 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008586 sizeof(posix_constants_confstr)
8587 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008588 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008589 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008590#endif
8591#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008592 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008593 sizeof(posix_constants_sysconf)
8594 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008595 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008596 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008597#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008598 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008599}
Fred Draked86ed291999-12-15 15:34:33 +00008600
8601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008602PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008603"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008604Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008605in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008606
8607static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008608posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008609{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008610 abort();
8611 /*NOTREACHED*/
8612 Py_FatalError("abort() called from Python code didn't abort!");
8613 return NULL;
8614}
Fred Drakebec628d1999-12-15 18:31:10 +00008615
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008616#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008617PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008618"startfile(filepath [, operation]) - Start a file with its associated\n\
8619application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008620\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008621When \"operation\" is not specified or \"open\", this acts like\n\
8622double-clicking the file in Explorer, or giving the file name as an\n\
8623argument to the DOS \"start\" command: the file is opened with whatever\n\
8624application (if any) its extension is associated.\n\
8625When another \"operation\" is given, it specifies what should be done with\n\
8626the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008627\n\
8628startfile returns as soon as the associated application is launched.\n\
8629There is no option to wait for the application to close, and no way\n\
8630to retrieve the application's exit status.\n\
8631\n\
8632The filepath is relative to the current directory. If you want to use\n\
8633an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008634the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008635
8636static PyObject *
8637win32_startfile(PyObject *self, PyObject *args)
8638{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008639 char *filepath;
8640 char *operation = NULL;
8641 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008642
Victor Stinnerd6f85422010-05-05 23:33:33 +00008643 PyObject *unipath, *woperation = NULL;
8644 if (!PyArg_ParseTuple(args, "U|s:startfile",
8645 &unipath, &operation)) {
8646 PyErr_Clear();
8647 goto normal;
8648 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008649
Victor Stinnerd6f85422010-05-05 23:33:33 +00008650 if (operation) {
8651 woperation = PyUnicode_DecodeASCII(operation,
8652 strlen(operation), NULL);
8653 if (!woperation) {
8654 PyErr_Clear();
8655 operation = NULL;
8656 goto normal;
8657 }
8658 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008659
Victor Stinnerd6f85422010-05-05 23:33:33 +00008660 Py_BEGIN_ALLOW_THREADS
8661 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8662 PyUnicode_AS_UNICODE(unipath),
8663 NULL, NULL, SW_SHOWNORMAL);
8664 Py_END_ALLOW_THREADS
8665
8666 Py_XDECREF(woperation);
8667 if (rc <= (HINSTANCE)32) {
8668 PyObject *errval = win32_error_unicode("startfile",
8669 PyUnicode_AS_UNICODE(unipath));
8670 return errval;
8671 }
8672 Py_INCREF(Py_None);
8673 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008674
8675normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008676 if (!PyArg_ParseTuple(args, "et|s:startfile",
8677 Py_FileSystemDefaultEncoding, &filepath,
8678 &operation))
8679 return NULL;
8680 Py_BEGIN_ALLOW_THREADS
8681 rc = ShellExecute((HWND)0, operation, filepath,
8682 NULL, NULL, SW_SHOWNORMAL);
8683 Py_END_ALLOW_THREADS
8684 if (rc <= (HINSTANCE)32) {
8685 PyObject *errval = win32_error("startfile", filepath);
8686 PyMem_Free(filepath);
8687 return errval;
8688 }
8689 PyMem_Free(filepath);
8690 Py_INCREF(Py_None);
8691 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008692}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008693#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008694
Martin v. Löwis438b5342002-12-27 10:16:42 +00008695#ifdef HAVE_GETLOADAVG
8696PyDoc_STRVAR(posix_getloadavg__doc__,
8697"getloadavg() -> (float, float, float)\n\n\
8698Return the number of processes in the system run queue averaged over\n\
8699the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8700was unobtainable");
8701
8702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008703posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008704{
8705 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008706 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008707 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8708 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008709 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008710 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008711}
8712#endif
8713
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008714PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008715"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008716Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008717
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008718static PyObject *
8719posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008720{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008721 Py_ssize_t size;
8722 PyObject *result;
8723 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008724
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008725 /* Read arguments */
8726 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008727 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008728 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008729 return PyErr_Format(PyExc_ValueError,
8730 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008731 result = PyBytes_FromStringAndSize(NULL, size);
8732 if (result == NULL)
8733 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008734
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008735 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8736 PyBytes_GET_SIZE(result));
8737 if (ret == -1) {
8738 Py_DECREF(result);
8739 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008740 }
8741 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008742}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008743
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008744#ifdef HAVE_SETRESUID
8745PyDoc_STRVAR(posix_setresuid__doc__,
8746"setresuid(ruid, euid, suid)\n\n\
8747Set the current process's real, effective, and saved user ids.");
8748
8749static PyObject*
8750posix_setresuid (PyObject *self, PyObject *args)
8751{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008752 uid_t ruid, euid, suid;
8753 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8754 _Py_Uid_Converter, &ruid,
8755 _Py_Uid_Converter, &euid,
8756 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008757 return NULL;
8758 if (setresuid(ruid, euid, suid) < 0)
8759 return posix_error();
8760 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008761}
8762#endif
8763
8764#ifdef HAVE_SETRESGID
8765PyDoc_STRVAR(posix_setresgid__doc__,
8766"setresgid(rgid, egid, sgid)\n\n\
8767Set the current process's real, effective, and saved group ids.");
8768
8769static PyObject*
8770posix_setresgid (PyObject *self, PyObject *args)
8771{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008772 gid_t rgid, egid, sgid;
8773 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8774 _Py_Gid_Converter, &rgid,
8775 _Py_Gid_Converter, &egid,
8776 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008777 return NULL;
8778 if (setresgid(rgid, egid, sgid) < 0)
8779 return posix_error();
8780 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008781}
8782#endif
8783
8784#ifdef HAVE_GETRESUID
8785PyDoc_STRVAR(posix_getresuid__doc__,
8786"getresuid() -> (ruid, euid, suid)\n\n\
8787Get tuple of the current process's real, effective, and saved user ids.");
8788
8789static PyObject*
8790posix_getresuid (PyObject *self, PyObject *noargs)
8791{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008792 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008793 if (getresuid(&ruid, &euid, &suid) < 0)
8794 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008795 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8796 _PyInt_FromUid(euid),
8797 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008798}
8799#endif
8800
8801#ifdef HAVE_GETRESGID
8802PyDoc_STRVAR(posix_getresgid__doc__,
8803"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008804Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008805
8806static PyObject*
8807posix_getresgid (PyObject *self, PyObject *noargs)
8808{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008809 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008810 if (getresgid(&rgid, &egid, &sgid) < 0)
8811 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008812 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8813 _PyInt_FromGid(egid),
8814 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008815}
8816#endif
8817
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008818static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008819 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008820#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008821 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008822#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008823 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008824#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008825 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008826#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008828#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008829 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008830#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008831#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008832 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008833#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008834#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008835 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008836#endif /* HAVE_LCHMOD */
8837#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008838 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008839#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008840#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008841 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008842#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008843#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008844 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008845#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008846#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008847 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008848#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008849#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008850 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008851#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008852#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008853 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008854#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008855 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008856#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008857#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008858#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008859 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008860#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8862 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8863 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008864#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008866#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008867#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008869#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008870 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8871 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8872 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8873 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008874#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008875 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008876#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008877#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008878 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008879#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008881#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008883#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008884 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8885 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8886 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008887#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008888 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008889#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008890 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008891#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8893 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008894#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008895#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008896 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8897 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008898#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008899 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8900 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008901#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008902#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008903#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008904 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008905#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008906#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008908#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008909#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008910 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008911#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008912#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008913 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008914#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008915#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008916 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008917#endif /* HAVE_GETEGID */
8918#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008919 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008920#endif /* HAVE_GETEUID */
8921#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008922 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008923#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008924#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008925 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008926#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008927 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008928#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008930#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008931#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008933#endif /* HAVE_GETPPID */
8934#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008936#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008937#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008938 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008939#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008940#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008941 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008942#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008943#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008944 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008945#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008946#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008947 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008948#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008949#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008950 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008951#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"popen2", win32_popen2, METH_VARARGS},
8953 {"popen3", win32_popen3, METH_VARARGS},
8954 {"popen4", win32_popen4, METH_VARARGS},
8955 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8956 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008957#else
8958#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008959 {"popen2", os2emx_popen2, METH_VARARGS},
8960 {"popen3", os2emx_popen3, METH_VARARGS},
8961 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008962#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008963#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008964#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008965#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008966 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008967#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008968#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008969 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008970#endif /* HAVE_SETEUID */
8971#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008972 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008973#endif /* HAVE_SETEGID */
8974#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008975 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008976#endif /* HAVE_SETREUID */
8977#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008978 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008979#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008980#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008981 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008982#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008983#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008984 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008985#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008986#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008987 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008988#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008989#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008990 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008991#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008992#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008993 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008994#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008995#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008996 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008997#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008998#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008999 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009000#endif /* HAVE_WAIT3 */
9001#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009002 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009003#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009004#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009005 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009006#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009007#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009008 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009009#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009010#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009011 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009012#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009013#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009014 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009015#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009016#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009017 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009018#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009019#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009020 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009021#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009022 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009023 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009024 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9025 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9026 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9027 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9028 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9029 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9030 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9031 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9032 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009033#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009034 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009035#endif
9036#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009038#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009039#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009040 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009041#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009042#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009043 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9044 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9045 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009046#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009047#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009048 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009049#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009050#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009051 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009052#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009053#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009054 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009055#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009056 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009057#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009059#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009060#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009061 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009062#endif
9063#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009064 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009065#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009066#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009067#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009069#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009070#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009071 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009072#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009073#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009074 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009075#endif /* WIFSTOPPED */
9076#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009077 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009078#endif /* WIFSIGNALED */
9079#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009080 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009081#endif /* WIFEXITED */
9082#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009083 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009084#endif /* WEXITSTATUS */
9085#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009086 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009087#endif /* WTERMSIG */
9088#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009090#endif /* WSTOPSIG */
9091#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009092#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009093 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009094#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009095#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009096 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009097#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009098#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009099 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009100#endif
9101#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009102 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009103#endif
9104#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009105 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009106#endif
Fred Drakec9680921999-12-13 16:37:25 +00009107#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009108 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009109#endif
9110#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009111 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009112#endif
9113#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009114 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009115#endif
9116#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009117 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009119 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009120#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009122 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009123#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009124#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009126#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009127#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009128 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009129#endif
9130#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009131 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009132#endif
9133#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009134 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009135#endif
9136#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009137 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009138#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009139 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009140 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009141};
9142
9143
Barry Warsaw4a342091996-12-19 23:50:02 +00009144static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009145ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009146{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009147 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009148}
9149
Guido van Rossumd48f2521997-12-05 22:19:34 +00009150#if defined(PYOS_OS2)
9151/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009152static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009153{
9154 APIRET rc;
9155 ULONG values[QSV_MAX+1];
9156 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009157 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009158
9159 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009160 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009161 Py_END_ALLOW_THREADS
9162
9163 if (rc != NO_ERROR) {
9164 os2_error(rc);
9165 return -1;
9166 }
9167
Fred Drake4d1e64b2002-04-15 19:40:07 +00009168 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9169 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9170 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9171 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9172 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9173 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9174 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009175
9176 switch (values[QSV_VERSION_MINOR]) {
9177 case 0: ver = "2.00"; break;
9178 case 10: ver = "2.10"; break;
9179 case 11: ver = "2.11"; break;
9180 case 30: ver = "3.00"; break;
9181 case 40: ver = "4.00"; break;
9182 case 50: ver = "5.00"; break;
9183 default:
Tim Peters885d4572001-11-28 20:27:42 +00009184 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009185 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009186 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009187 ver = &tmp[0];
9188 }
9189
9190 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009191 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009192 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009193
9194 /* Add Indicator of Which Drive was Used to Boot the System */
9195 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9196 tmp[1] = ':';
9197 tmp[2] = '\0';
9198
Fred Drake4d1e64b2002-04-15 19:40:07 +00009199 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009200}
9201#endif
9202
Barry Warsaw4a342091996-12-19 23:50:02 +00009203static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009204all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009205{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009206#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009207 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009208#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009209#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009210 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009211#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009212#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009213 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009214#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009215#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009216 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009217#endif
Fred Drakec9680921999-12-13 16:37:25 +00009218#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009219 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009220#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009221#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009222 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009223#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009224#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009225 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009226#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009227#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009228 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009229#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009230#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009231 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009232#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009233#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009234 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009235#endif
9236#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009237 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009238#endif
9239#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009240 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009241#endif
9242#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009243 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009244#endif
9245#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009246 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009247#endif
9248#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009249 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009250#endif
9251#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009253#endif
9254#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009255 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009256#endif
9257#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009258 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009259#endif
9260#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009262#endif
9263#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009264 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009265#endif
9266#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009267 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009268#endif
9269#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009270 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009271#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009272#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009273 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009274#endif
9275#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009276 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009277#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009278#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009279 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009280#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009281#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009282 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009283#endif
9284#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009285 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009286#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009287
Tim Peters5aa91602002-01-30 05:46:57 +00009288/* MS Windows */
9289#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009290 /* Don't inherit in child processes. */
9291 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009292#endif
9293#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009294 /* Optimize for short life (keep in memory). */
9295 /* MS forgot to define this one with a non-underscore form too. */
9296 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009297#endif
9298#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009299 /* Automatically delete when last handle is closed. */
9300 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009301#endif
9302#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009303 /* Optimize for random access. */
9304 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009305#endif
9306#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009307 /* Optimize for sequential access. */
9308 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009309#endif
9310
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009311/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009312#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009313 /* Send a SIGIO signal whenever input or output
9314 becomes available on file descriptor */
9315 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009316#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009317#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009318 /* Direct disk access. */
9319 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009320#endif
9321#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009322 /* Must be a directory. */
9323 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009324#endif
9325#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009326 /* Do not follow links. */
9327 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009328#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009329#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 /* Do not update the access time. */
9331 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009332#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009333
Victor Stinnerd6f85422010-05-05 23:33:33 +00009334 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009335#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009336 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009337#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009338#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009340#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009341#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009342 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009343#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009344#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009345 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009346#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009347#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009348 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009349#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009350#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009351 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009352#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009353#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009354 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009355#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009356#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009357 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009358#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009359#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009360 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009361#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009362#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009363 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009364#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009365#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009366 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009367#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009368#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009369 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009370#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009371#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009372 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009373#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009374#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009375 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009376#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009377#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009378 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009379#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009380#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009381 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009382#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009383#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009384 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009385#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009386
Guido van Rossum246bc171999-02-01 23:54:31 +00009387#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009388#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009389 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9390 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9391 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9392 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9393 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9394 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9395 if (ins(d, "P_PM", (long)P_PM)) return -1;
9396 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9397 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9398 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9399 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9400 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9401 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9402 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9403 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9404 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9405 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9406 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9407 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9408 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009409#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009410 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9411 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9412 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9413 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9414 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009415#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009416#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009417
Guido van Rossumd48f2521997-12-05 22:19:34 +00009418#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009419 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009420#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009421 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009422}
9423
9424
Tim Peters5aa91602002-01-30 05:46:57 +00009425#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009426#define INITFUNC initnt
9427#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009428
9429#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009430#define INITFUNC initos2
9431#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009432
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009433#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009434#define INITFUNC initposix
9435#define MODNAME "posix"
9436#endif
9437
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009438PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009439INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009440{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009441 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009442
Victor Stinnerd6f85422010-05-05 23:33:33 +00009443 m = Py_InitModule3(MODNAME,
9444 posix_methods,
9445 posix__doc__);
9446 if (m == NULL)
9447 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009448
Victor Stinnerd6f85422010-05-05 23:33:33 +00009449 /* Initialize environ dictionary */
9450 v = convertenviron();
9451 Py_XINCREF(v);
9452 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9453 return;
9454 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009455
Victor Stinnerd6f85422010-05-05 23:33:33 +00009456 if (all_ins(m))
9457 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009458
Victor Stinnerd6f85422010-05-05 23:33:33 +00009459 if (setup_confname_tables(m))
9460 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009461
Victor Stinnerd6f85422010-05-05 23:33:33 +00009462 Py_INCREF(PyExc_OSError);
9463 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009464
Guido van Rossumb3d39562000-01-31 18:41:26 +00009465#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009466 if (posix_putenv_garbage == NULL)
9467 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009468#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009469
Victor Stinnerd6f85422010-05-05 23:33:33 +00009470 if (!initialized) {
9471 stat_result_desc.name = MODNAME ".stat_result";
9472 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9473 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9474 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9475 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9476 structseq_new = StatResultType.tp_new;
9477 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009478
Victor Stinnerd6f85422010-05-05 23:33:33 +00009479 statvfs_result_desc.name = MODNAME ".statvfs_result";
9480 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009481#ifdef NEED_TICKS_PER_SECOND
9482# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009483 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009484# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009485 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009486# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009487 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009488# endif
9489#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009490 }
9491 Py_INCREF((PyObject*) &StatResultType);
9492 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9493 Py_INCREF((PyObject*) &StatVFSResultType);
9494 PyModule_AddObject(m, "statvfs_result",
9495 (PyObject*) &StatVFSResultType);
9496 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009497
9498#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009499 /*
9500 * Step 2 of weak-linking support on Mac OS X.
9501 *
9502 * The code below removes functions that are not available on the
9503 * currently active platform.
9504 *
9505 * This block allow one to use a python binary that was build on
9506 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9507 * OSX 10.4.
9508 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009509#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009510 if (fstatvfs == NULL) {
9511 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9512 return;
9513 }
9514 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009515#endif /* HAVE_FSTATVFS */
9516
9517#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009518 if (statvfs == NULL) {
9519 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9520 return;
9521 }
9522 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009523#endif /* HAVE_STATVFS */
9524
9525# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009526 if (lchown == NULL) {
9527 if (PyObject_DelAttrString(m, "lchown") == -1) {
9528 return;
9529 }
9530 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009531#endif /* HAVE_LCHOWN */
9532
9533
9534#endif /* __APPLE__ */
9535
Guido van Rossumb6775db1994-08-01 11:34:53 +00009536}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009537
9538#ifdef __cplusplus
9539}
9540#endif
9541
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009542