blob: 72bf7d206c5a5cb59dce4320fdeff9e48442a41a [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Ronald Oussorend06b6f22006-04-23 11:59:25 +000014#ifdef __APPLE__
15 /*
Victor Stinnerd6f85422010-05-05 23:33:33 +000016 * Step 1 of support for weak-linking a number of symbols existing on
Ronald Oussorend06b6f22006-04-23 11:59:25 +000017 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
18 * at the end of this file for more information.
19 */
20# pragma weak lchown
21# pragma weak statvfs
22# pragma weak fstatvfs
23
24#endif /* __APPLE__ */
25
Thomas Wouters68bc4f92006-03-01 01:05:10 +000026#define PY_SSIZE_T_CLEAN
27
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000028#include "Python.h"
29#include "structseq.h"
Serhiy Storchakada5c2a02013-02-12 09:27:53 +020030#ifndef MS_WINDOWS
31#include "posixmodule.h"
32#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000033
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000036#endif /* defined(__VMS) */
37
Anthony Baxterac6bd462006-04-13 02:06:09 +000038#ifdef __cplusplus
39extern "C" {
40#endif
41
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000042PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000043"This module provides access to operating system functionality that is\n\
44standardized by the C Standard and the POSIX standard (a thinly\n\
45disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000046corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000048#ifndef Py_USING_UNICODE
49/* This is used in signatures of functions. */
50#define Py_UNICODE void
51#endif
52
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000053#if defined(PYOS_OS2)
54#define INCL_DOS
55#define INCL_DOSERRORS
56#define INCL_DOSPROCESS
57#define INCL_NOPMAPI
58#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000059#if defined(PYCC_GCC)
60#include <ctype.h>
61#include <io.h>
62#include <stdio.h>
63#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000064#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000065#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000066#endif
67
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000068#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000069#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000070#endif /* HAVE_SYS_TYPES_H */
71
72#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000073#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000074#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000075
Guido van Rossum36bc6801995-06-14 22:54:23 +000076#ifdef HAVE_SYS_WAIT_H
Victor Stinnerd6f85422010-05-05 23:33:33 +000077#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000078#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000079
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000080#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000081#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000082#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000083
Guido van Rossumb6775db1994-08-01 11:34:53 +000084#ifdef HAVE_FCNTL_H
85#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000086#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Guido van Rossuma6535fd2001-10-18 19:44:10 +000088#ifdef HAVE_GRP_H
89#include <grp.h>
90#endif
91
Barry Warsaw5676bd12003-01-07 20:57:09 +000092#ifdef HAVE_SYSEXITS_H
93#include <sysexits.h>
94#endif /* HAVE_SYSEXITS_H */
95
Anthony Baxter8a560de2004-10-13 15:30:56 +000096#ifdef HAVE_SYS_LOADAVG_H
97#include <sys/loadavg.h>
98#endif
99
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000100/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000101/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000103#include <process.h>
104#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000105#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000106#define HAVE_GETCWD 1
107#define HAVE_OPENDIR 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000108#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#if defined(__OS2__)
110#define HAVE_EXECV 1
111#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#include <process.h>
114#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000115#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000116#define HAVE_EXECV 1
117#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_OPENDIR 1
119#define HAVE_PIPE 1
120#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000121#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000122#define HAVE_WAIT 1
123#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000124#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000125#define HAVE_GETCWD 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000126#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_EXECV 1
128#define HAVE_PIPE 1
129#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000130#define HAVE_SYSTEM 1
131#define HAVE_CWAIT 1
132#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000133#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000134#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000135#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
136/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinnerd6f85422010-05-05 23:33:33 +0000137#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138/* Unix functions that the configure script doesn't check for */
139#define HAVE_EXECV 1
140#define HAVE_FORK 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000141#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000142#define HAVE_FORK1 1
143#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#define HAVE_GETCWD 1
145#define HAVE_GETEGID 1
146#define HAVE_GETEUID 1
147#define HAVE_GETGID 1
148#define HAVE_GETPPID 1
149#define HAVE_GETUID 1
150#define HAVE_KILL 1
151#define HAVE_OPENDIR 1
152#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000153#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000155#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000156#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#define HAVE_WAIT 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000158#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000159#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#endif /* _MSC_VER */
161#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000162#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000164
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000166
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000167#if defined(__sgi)&&_COMPILER_VERSION>=700
168/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
169 (default) */
170extern char *ctermid_r(char *);
171#endif
172
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000173#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000174#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000176#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000177#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000179#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000182#endif
183#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chdir(char *);
185extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000186#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chdir(const char *);
188extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000189#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000190#ifdef __BORLANDC__
191extern int chmod(const char *, int);
192#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000194#endif
Christian Heimes36281872007-11-30 21:11:28 +0000195/*#ifdef HAVE_FCHMOD
196extern int fchmod(int, mode_t);
197#endif*/
198/*#ifdef HAVE_LCHMOD
199extern int lchmod(const char *, mode_t);
200#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000201extern int chown(const char *, uid_t, gid_t);
202extern char *getcwd(char *, int);
203extern char *strerror(int);
204extern int link(const char *, const char *);
205extern int rename(const char *, const char *);
206extern int stat(const char *, struct stat *);
207extern int unlink(const char *);
208extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000211#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000213extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000216
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#ifdef HAVE_UTIME_H
220#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000223#ifdef HAVE_SYS_UTIME_H
224#include <sys/utime.h>
225#define HAVE_UTIME_H /* pretend we do for the rest of this file */
226#endif /* HAVE_SYS_UTIME_H */
227
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#ifdef HAVE_SYS_TIMES_H
229#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000230#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231
232#ifdef HAVE_SYS_PARAM_H
233#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000234#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
236#ifdef HAVE_SYS_UTSNAME_H
237#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000240#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) strlen((dirent)->d_name)
243#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000244#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#include <direct.h>
246#define NAMLEN(dirent) strlen((dirent)->d_name)
247#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000250#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000251#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#endif
257#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#endif
260#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000263#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000265#endif
266#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000268#endif
269#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000271#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000272#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000273#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <windows.h>
Victor Stinnerd6f85422010-05-05 23:33:33 +0000275#include <shellapi.h> /* for ShellExecute() */
276#define popen _popen
277#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000278#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279
Guido van Rossumd48f2521997-12-05 22:19:34 +0000280#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000282#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
Tim Petersbc2e10e2002-03-03 23:17:02 +0000284#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000285#if defined(PATH_MAX) && PATH_MAX > 1024
286#define MAXPATHLEN PATH_MAX
287#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000288#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000289#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000290#endif /* MAXPATHLEN */
291
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000292#ifdef UNION_WAIT
293/* Emulate some macros on systems that have a union instead of macros */
294
295#ifndef WIFEXITED
296#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
297#endif
298
299#ifndef WEXITSTATUS
300#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
301#endif
302
303#ifndef WTERMSIG
304#define WTERMSIG(u_wait) ((u_wait).w_termsig)
305#endif
306
Neal Norwitzd5a37542006-03-20 06:48:34 +0000307#define WAIT_TYPE union wait
308#define WAIT_STATUS_INT(s) (s.w_status)
309
310#else /* !UNION_WAIT */
311#define WAIT_TYPE int
312#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000313#endif /* UNION_WAIT */
314
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000315/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000316#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000317#define PARSE_PID "i"
318#define PyLong_FromPid PyInt_FromLong
319#define PyLong_AsPid PyInt_AsLong
320#elif SIZEOF_PID_T == SIZEOF_LONG
321#define PARSE_PID "l"
322#define PyLong_FromPid PyInt_FromLong
323#define PyLong_AsPid PyInt_AsLong
324#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
325#define PARSE_PID "L"
326#define PyLong_FromPid PyLong_FromLongLong
327#define PyLong_AsPid PyInt_AsLongLong
328#else
329#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000330#endif /* SIZEOF_PID_T */
331
Greg Wardb48bc172000-03-01 21:51:56 +0000332/* Don't use the "_r" form if we don't need it (also, won't have a
333 prototype for it, at least on Solaris -- maybe others as well?). */
334#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
335#define USE_CTERMID_R
336#endif
337
338#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
339#define USE_TMPNAM_R
340#endif
341
Tim Peters11b23062003-04-23 02:39:17 +0000342#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000343#include <sys/mkdev.h>
344#else
345#if defined(MAJOR_IN_SYSMACROS)
346#include <sys/sysmacros.h>
347#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000348#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
349#include <sys/mkdev.h>
350#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000351#endif
Fred Drake699f3522000-06-29 21:12:41 +0000352
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200353
354#ifndef MS_WINDOWS
355PyObject *
356_PyInt_FromUid(uid_t uid)
357{
358 if (uid <= LONG_MAX)
359 return PyInt_FromLong(uid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500360 return PyLong_FromUnsignedLong(uid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200361}
362
363PyObject *
364_PyInt_FromGid(gid_t gid)
365{
366 if (gid <= LONG_MAX)
367 return PyInt_FromLong(gid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500368 return PyLong_FromUnsignedLong(gid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200369}
370
371int
372_Py_Uid_Converter(PyObject *obj, void *p)
373{
374 int overflow;
375 long result;
376 if (PyFloat_Check(obj)) {
377 PyErr_SetString(PyExc_TypeError,
378 "integer argument expected, got float");
379 return 0;
380 }
381 result = PyLong_AsLongAndOverflow(obj, &overflow);
382 if (overflow < 0)
383 goto OverflowDown;
384 if (!overflow && result == -1) {
385 /* error or -1 */
386 if (PyErr_Occurred())
387 return 0;
388 *(uid_t *)p = (uid_t)-1;
389 }
390 else {
391 /* unsigned uid_t */
392 unsigned long uresult;
393 if (overflow > 0) {
394 uresult = PyLong_AsUnsignedLong(obj);
395 if (PyErr_Occurred()) {
396 if (PyErr_ExceptionMatches(PyExc_OverflowError))
397 goto OverflowUp;
398 return 0;
399 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200400 } else {
401 if (result < 0)
402 goto OverflowDown;
403 uresult = result;
404 }
405 if (sizeof(uid_t) < sizeof(long) &&
406 (unsigned long)(uid_t)uresult != uresult)
407 goto OverflowUp;
408 *(uid_t *)p = (uid_t)uresult;
409 }
410 return 1;
411
412OverflowDown:
413 PyErr_SetString(PyExc_OverflowError,
414 "user id is less than minimum");
415 return 0;
416
417OverflowUp:
418 PyErr_SetString(PyExc_OverflowError,
419 "user id is greater than maximum");
420 return 0;
421}
422
423int
424_Py_Gid_Converter(PyObject *obj, void *p)
425{
426 int overflow;
427 long result;
428 if (PyFloat_Check(obj)) {
429 PyErr_SetString(PyExc_TypeError,
430 "integer argument expected, got float");
431 return 0;
432 }
433 result = PyLong_AsLongAndOverflow(obj, &overflow);
434 if (overflow < 0)
435 goto OverflowDown;
436 if (!overflow && result == -1) {
437 /* error or -1 */
438 if (PyErr_Occurred())
439 return 0;
440 *(gid_t *)p = (gid_t)-1;
441 }
442 else {
443 /* unsigned gid_t */
444 unsigned long uresult;
445 if (overflow > 0) {
446 uresult = PyLong_AsUnsignedLong(obj);
447 if (PyErr_Occurred()) {
448 if (PyErr_ExceptionMatches(PyExc_OverflowError))
449 goto OverflowUp;
450 return 0;
451 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200452 } else {
453 if (result < 0)
454 goto OverflowDown;
455 uresult = result;
456 }
457 if (sizeof(gid_t) < sizeof(long) &&
458 (unsigned long)(gid_t)uresult != uresult)
459 goto OverflowUp;
460 *(gid_t *)p = (gid_t)uresult;
461 }
462 return 1;
463
464OverflowDown:
465 PyErr_SetString(PyExc_OverflowError,
466 "group id is less than minimum");
467 return 0;
468
469OverflowUp:
470 PyErr_SetString(PyExc_OverflowError,
471 "group id is greater than maximum");
472 return 0;
473}
474#endif /* MS_WINDOWS */
475
476
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200477#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
478static int
479_Py_Dev_Converter(PyObject *obj, void *p)
480{
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300481 PyObject *index = PyNumber_Index(obj);
482 if (index == NULL)
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200483 return 0;
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300484 if (PyInt_Check(index)) {
485 long x = PyInt_AS_LONG(index);
486 Py_DECREF(index);
487 if (x == -1 && PyErr_Occurred())
488 return 0;
489 if (x < 0) {
490 PyErr_SetString(PyExc_OverflowError,
491 "can't convert negative number to unsigned long");
492 return 0;
493 }
494 *((dev_t *)p) = (unsigned long)x;
495 }
496 else if (PyLong_Check(index)) {
497#ifdef HAVE_LONG_LONG
498 *((dev_t *)p) = PyLong_AsUnsignedLongLong(index);
499#else
500 *((dev_t *)p) = PyLong_AsUnsignedLong(index);
501#endif
502 Py_DECREF(index);
503 if (PyErr_Occurred())
504 return 0;
505 }
506 else {
507 Py_DECREF(index);
508 PyErr_Format(PyExc_TypeError,
509 "expected int/long, %s found",
510 Py_TYPE(obj)->tp_name);
511 return 0;
512 }
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200513 return 1;
514}
515
Serhiy Storchakabe8c6ae2015-07-12 16:41:29 +0300516#endif
517
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200518#ifdef HAVE_LONG_LONG
519static PyObject *
520_PyInt_FromDev(PY_LONG_LONG v)
521{
522 if (LONG_MIN <= v && v <= LONG_MAX)
523 return PyInt_FromLong((long)v);
524 else
525 return PyLong_FromLongLong(v);
526}
527#else
528# define _PyInt_FromDev PyInt_FromLong
529#endif
530
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200531
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000532#if defined _MSC_VER && _MSC_VER >= 1400
533/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov4bb142b2012-12-18 21:27:37 +0200534 * valid and raise an assertion if it isn't.
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000535 * Normally, an invalid fd is likely to be a C program error and therefore
536 * an assertion can be useful, but it does contradict the POSIX standard
537 * which for write(2) states:
538 * "Otherwise, -1 shall be returned and errno set to indicate the error."
539 * "[EBADF] The fildes argument is not a valid file descriptor open for
540 * writing."
541 * Furthermore, python allows the user to enter any old integer
542 * as a fd and should merely raise a python exception on error.
543 * The Microsoft CRT doesn't provide an official way to check for the
544 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000545 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000546 * internal structures involved.
547 * The structures below must be updated for each version of visual studio
548 * according to the file internal.h in the CRT source, until MS comes
549 * up with a less hacky way to do this.
550 * (all of this is to avoid globally modifying the CRT behaviour using
551 * _set_invalid_parameter_handler() and _CrtSetReportMode())
552 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000553/* The actual size of the structure is determined at runtime.
554 * Only the first items must be present.
555 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000556typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000557 intptr_t osfhnd;
558 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000559} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000560
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000561extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000562#define IOINFO_L2E 5
563#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
564#define IOINFO_ARRAYS 64
565#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
566#define FOPEN 0x01
567#define _NO_CONSOLE_FILENO (intptr_t)-2
568
569/* This function emulates what the windows CRT does to validate file handles */
570int
571_PyVerify_fd(int fd)
572{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000573 const int i1 = fd >> IOINFO_L2E;
574 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000575
Victor Stinnerd6f85422010-05-05 23:33:33 +0000576 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000577
Victor Stinnerd6f85422010-05-05 23:33:33 +0000578 /* Determine the actual size of the ioinfo structure,
579 * as used by the CRT loaded in memory
580 */
581 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
582 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
583 }
584 if (sizeof_ioinfo == 0) {
585 /* This should not happen... */
586 goto fail;
587 }
588
589 /* See that it isn't a special CLEAR fileno */
590 if (fd != _NO_CONSOLE_FILENO) {
591 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
592 * we check pointer validity and other info
593 */
594 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
595 /* finally, check that the file is open */
596 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
597 if (info->osfile & FOPEN) {
598 return 1;
599 }
600 }
601 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000602 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000603 errno = EBADF;
604 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000605}
606
607/* the special case of checking dup2. The target fd must be in a sensible range */
608static int
609_PyVerify_fd_dup2(int fd1, int fd2)
610{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000611 if (!_PyVerify_fd(fd1))
612 return 0;
613 if (fd2 == _NO_CONSOLE_FILENO)
614 return 0;
615 if ((unsigned)fd2 < _NHANDLE_)
616 return 1;
617 else
618 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000619}
620#else
621/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
622#define _PyVerify_fd_dup2(A, B) (1)
623#endif
624
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000625/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100626#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000627/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100628** environ directly, we must obtain it with _NSGetEnviron(). See also
629** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000630*/
631#include <crt_externs.h>
632static char **environ;
633#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000635#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000636
Barry Warsaw53699e91996-12-10 23:23:01 +0000637static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000638convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000640 PyObject *d;
641 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000642#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000643 APIRET rc;
644 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
645#endif
646 d = PyDict_New();
647 if (d == NULL)
648 return NULL;
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100649#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinnerd6f85422010-05-05 23:33:33 +0000650 if (environ == NULL)
651 environ = *_NSGetEnviron();
652#endif
653 if (environ == NULL)
654 return d;
655 /* This part ignores errors */
656 for (e = environ; *e != NULL; e++) {
657 PyObject *k;
658 PyObject *v;
659 char *p = strchr(*e, '=');
660 if (p == NULL)
661 continue;
662 k = PyString_FromStringAndSize(*e, (int)(p-*e));
663 if (k == NULL) {
664 PyErr_Clear();
665 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000666 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000667 v = PyString_FromString(p+1);
668 if (v == NULL) {
669 PyErr_Clear();
670 Py_DECREF(k);
671 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000672 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000673 if (PyDict_GetItem(d, k) == NULL) {
674 if (PyDict_SetItem(d, k, v) != 0)
675 PyErr_Clear();
676 }
677 Py_DECREF(k);
678 Py_DECREF(v);
679 }
680#if defined(PYOS_OS2)
681 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
682 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
683 PyObject *v = PyString_FromString(buffer);
684 PyDict_SetItemString(d, "BEGINLIBPATH", v);
685 Py_DECREF(v);
686 }
687 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
688 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
689 PyObject *v = PyString_FromString(buffer);
690 PyDict_SetItemString(d, "ENDLIBPATH", v);
691 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000692 }
693#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000694 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000695}
696
697
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698/* Set a POSIX-specific error from errno, and return NULL */
699
Barry Warsawd58d7641998-07-23 16:14:40 +0000700static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000701posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000702{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000703 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704}
Barry Warsawd58d7641998-07-23 16:14:40 +0000705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000706posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000707{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000708 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000709}
710
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000711#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000712static PyObject *
713posix_error_with_unicode_filename(Py_UNICODE* name)
714{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000715 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000716}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000717#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000718
719
Mark Hammondef8b6542001-05-13 08:04:26 +0000720static PyObject *
721posix_error_with_allocated_filename(char* name)
722{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000723 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
724 PyMem_Free(name);
725 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000726}
727
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000728#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000729static PyObject *
730win32_error(char* function, char* filename)
731{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000732 /* XXX We should pass the function name along in the future.
733 (_winreg.c also wants to pass the function name.)
734 This would however require an additional param to the
735 Windows error object, which is non-trivial.
736 */
737 errno = GetLastError();
738 if (filename)
739 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
740 else
741 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000742}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000743
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000744static PyObject *
745win32_error_unicode(char* function, Py_UNICODE* filename)
746{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000747 /* XXX - see win32_error for comments on 'function' */
748 errno = GetLastError();
749 if (filename)
750 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
751 else
752 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000753}
754
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000755static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000756convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000757{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000758 if (PyUnicode_CheckExact(*param))
759 Py_INCREF(*param);
760 else if (PyUnicode_Check(*param))
761 /* For a Unicode subtype that's not a Unicode object,
762 return a true Unicode object with the same data. */
763 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
764 PyUnicode_GET_SIZE(*param));
765 else
766 *param = PyUnicode_FromEncodedObject(*param,
767 Py_FileSystemDefaultEncoding,
768 "strict");
769 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000770}
771
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000772#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773
Guido van Rossumd48f2521997-12-05 22:19:34 +0000774#if defined(PYOS_OS2)
775/**********************************************************************
776 * Helper Function to Trim and Format OS/2 Messages
777 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000778static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000779os2_formatmsg(char *msgbuf, int msglen, char *reason)
780{
781 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
782
783 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000784 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000785
Victor Stinner862490a2010-05-06 00:03:44 +0000786 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
787 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000788 }
789
790 /* Add Optional Reason Text */
791 if (reason) {
792 strcat(msgbuf, " : ");
793 strcat(msgbuf, reason);
794 }
795}
796
797/**********************************************************************
798 * Decode an OS/2 Operating System Error Code
799 *
800 * A convenience function to lookup an OS/2 error code and return a
801 * text message we can use to raise a Python exception.
802 *
803 * Notes:
804 * The messages for errors returned from the OS/2 kernel reside in
805 * the file OSO001.MSG in the \OS2 directory hierarchy.
806 *
807 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000808static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000809os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
810{
811 APIRET rc;
812 ULONG msglen;
813
814 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
815 Py_BEGIN_ALLOW_THREADS
816 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
817 errorcode, "oso001.msg", &msglen);
818 Py_END_ALLOW_THREADS
819
820 if (rc == NO_ERROR)
821 os2_formatmsg(msgbuf, msglen, reason);
822 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000823 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000824 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000825
826 return msgbuf;
827}
828
829/* Set an OS/2-specific error and return NULL. OS/2 kernel
830 errors are not in a global variable e.g. 'errno' nor are
831 they congruent with posix error numbers. */
832
Victor Stinnerd6f85422010-05-05 23:33:33 +0000833static PyObject *
834os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000835{
836 char text[1024];
837 PyObject *v;
838
839 os2_strerror(text, sizeof(text), code, "");
840
841 v = Py_BuildValue("(is)", code, text);
842 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000843 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000844 Py_DECREF(v);
845 }
846 return NULL; /* Signal to Python that an Exception is Pending */
847}
848
849#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000850
851/* POSIX generic methods */
852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000854posix_fildes(PyObject *fdobj, int (*func)(int))
855{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000856 int fd;
857 int res;
858 fd = PyObject_AsFileDescriptor(fdobj);
859 if (fd < 0)
860 return NULL;
861 if (!_PyVerify_fd(fd))
862 return posix_error();
863 Py_BEGIN_ALLOW_THREADS
864 res = (*func)(fd);
865 Py_END_ALLOW_THREADS
866 if (res < 0)
867 return posix_error();
868 Py_INCREF(Py_None);
869 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000870}
Guido van Rossum21142a01999-01-08 21:05:37 +0000871
872static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000873posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000874{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000875 char *path1 = NULL;
876 int res;
877 if (!PyArg_ParseTuple(args, format,
878 Py_FileSystemDefaultEncoding, &path1))
879 return NULL;
880 Py_BEGIN_ALLOW_THREADS
881 res = (*func)(path1);
882 Py_END_ALLOW_THREADS
883 if (res < 0)
884 return posix_error_with_allocated_filename(path1);
885 PyMem_Free(path1);
886 Py_INCREF(Py_None);
887 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000888}
889
Barry Warsaw53699e91996-12-10 23:23:01 +0000890static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000891posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000892 char *format,
893 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000894{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000895 char *path1 = NULL, *path2 = NULL;
896 int res;
897 if (!PyArg_ParseTuple(args, format,
898 Py_FileSystemDefaultEncoding, &path1,
899 Py_FileSystemDefaultEncoding, &path2))
900 return NULL;
901 Py_BEGIN_ALLOW_THREADS
902 res = (*func)(path1, path2);
903 Py_END_ALLOW_THREADS
904 PyMem_Free(path1);
905 PyMem_Free(path2);
906 if (res != 0)
907 /* XXX how to report both path1 and path2??? */
908 return posix_error();
909 Py_INCREF(Py_None);
910 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000911}
912
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000913#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000914static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000915win32_1str(PyObject* args, char* func,
916 char* format, BOOL (__stdcall *funcA)(LPCSTR),
917 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000918{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000919 PyObject *uni;
920 char *ansi;
921 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000922
Victor Stinnerd6f85422010-05-05 23:33:33 +0000923 if (!PyArg_ParseTuple(args, wformat, &uni))
924 PyErr_Clear();
925 else {
926 Py_BEGIN_ALLOW_THREADS
927 result = funcW(PyUnicode_AsUnicode(uni));
928 Py_END_ALLOW_THREADS
929 if (!result)
930 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
931 Py_INCREF(Py_None);
932 return Py_None;
933 }
934 if (!PyArg_ParseTuple(args, format, &ansi))
935 return NULL;
936 Py_BEGIN_ALLOW_THREADS
937 result = funcA(ansi);
938 Py_END_ALLOW_THREADS
939 if (!result)
940 return win32_error(func, ansi);
941 Py_INCREF(Py_None);
942 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000943
944}
945
946/* This is a reimplementation of the C library's chdir function,
947 but one that produces Win32 errors instead of DOS error codes.
948 chdir is essentially a wrapper around SetCurrentDirectory; however,
949 it also needs to set "magic" environment variables indicating
950 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000951static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000952win32_chdir(LPCSTR path)
953{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000954 char new_path[MAX_PATH+1];
955 int result;
956 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000957
Victor Stinnerd6f85422010-05-05 23:33:33 +0000958 if(!SetCurrentDirectoryA(path))
959 return FALSE;
960 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
961 if (!result)
962 return FALSE;
963 /* In the ANSI API, there should not be any paths longer
964 than MAX_PATH. */
965 assert(result <= MAX_PATH+1);
966 if (strncmp(new_path, "\\\\", 2) == 0 ||
967 strncmp(new_path, "//", 2) == 0)
968 /* UNC path, nothing to do. */
969 return TRUE;
970 env[1] = new_path[0];
971 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000972}
973
974/* The Unicode version differs from the ANSI version
975 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000976static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000977win32_wchdir(LPCWSTR path)
978{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000979 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
980 int result;
981 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000982
Victor Stinnerd6f85422010-05-05 23:33:33 +0000983 if(!SetCurrentDirectoryW(path))
984 return FALSE;
985 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
986 if (!result)
987 return FALSE;
988 if (result > MAX_PATH+1) {
989 new_path = malloc(result * sizeof(wchar_t));
990 if (!new_path) {
991 SetLastError(ERROR_OUTOFMEMORY);
992 return FALSE;
993 }
994 result = GetCurrentDirectoryW(result, new_path);
995 if (!result) {
996 free(new_path);
997 return FALSE;
998 }
999 }
1000 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1001 wcsncmp(new_path, L"//", 2) == 0)
1002 /* UNC path, nothing to do. */
1003 return TRUE;
1004 env[1] = new_path[0];
1005 result = SetEnvironmentVariableW(env, new_path);
1006 if (new_path != _new_path)
1007 free(new_path);
1008 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001009}
1010#endif
1011
Antoine Pitrouff48c0a2011-07-01 22:56:03 +02001012/* choose the appropriate stat and fstat functions and return structs */
1013#undef STAT
1014#undef FSTAT
1015#undef STRUCT_STAT
1016#if defined(MS_WIN64) || defined(MS_WINDOWS)
1017# define STAT win32_stat
1018# define FSTAT win32_fstat
1019# define STRUCT_STAT struct win32_stat
1020#else
1021# define STAT stat
1022# define FSTAT fstat
1023# define STRUCT_STAT struct stat
1024#endif
1025
Martin v. Löwis14694662006-02-03 12:54:16 +00001026#ifdef MS_WINDOWS
1027/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1028 - time stamps are restricted to second resolution
1029 - file modification times suffer from forth-and-back conversions between
1030 UTC and local time
1031 Therefore, we implement our own stat, based on the Win32 API directly.
1032*/
Victor Stinnerd6f85422010-05-05 23:33:33 +00001033#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001034
1035struct win32_stat{
1036 int st_dev;
1037 __int64 st_ino;
1038 unsigned short st_mode;
1039 int st_nlink;
1040 int st_uid;
1041 int st_gid;
1042 int st_rdev;
1043 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001044 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001045 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001046 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001047 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001048 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001049 int st_ctime_nsec;
1050};
1051
1052static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1053
1054static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001055FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001056{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001057 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1058 /* Cannot simply cast and dereference in_ptr,
1059 since it might not be aligned properly */
1060 __int64 in;
1061 memcpy(&in, in_ptr, sizeof(in));
1062 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001063 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001064}
1065
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001066static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001067time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001068{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001069 /* XXX endianness */
1070 __int64 out;
1071 out = time_in + secs_between_epochs;
1072 out = out * 10000000 + nsec_in / 100;
1073 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001074}
1075
Martin v. Löwis14694662006-02-03 12:54:16 +00001076/* Below, we *know* that ugo+r is 0444 */
1077#if _S_IREAD != 0400
1078#error Unsupported C library
1079#endif
1080static int
1081attributes_to_mode(DWORD attr)
1082{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001083 int m = 0;
1084 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1085 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1086 else
1087 m |= _S_IFREG;
1088 if (attr & FILE_ATTRIBUTE_READONLY)
1089 m |= 0444;
1090 else
1091 m |= 0666;
1092 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001093}
1094
1095static int
1096attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
1097{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001098 memset(result, 0, sizeof(*result));
1099 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1100 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1101 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1102 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1103 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001104
Victor Stinnerd6f85422010-05-05 23:33:33 +00001105 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001106}
1107
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001108static BOOL
1109attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001111 HANDLE hFindFile;
1112 WIN32_FIND_DATAA FileData;
1113 hFindFile = FindFirstFileA(pszFile, &FileData);
1114 if (hFindFile == INVALID_HANDLE_VALUE)
1115 return FALSE;
1116 FindClose(hFindFile);
1117 pfad->dwFileAttributes = FileData.dwFileAttributes;
1118 pfad->ftCreationTime = FileData.ftCreationTime;
1119 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1120 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1121 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1122 pfad->nFileSizeLow = FileData.nFileSizeLow;
1123 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001124}
1125
1126static BOOL
1127attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1128{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001129 HANDLE hFindFile;
1130 WIN32_FIND_DATAW FileData;
1131 hFindFile = FindFirstFileW(pszFile, &FileData);
1132 if (hFindFile == INVALID_HANDLE_VALUE)
1133 return FALSE;
1134 FindClose(hFindFile);
1135 pfad->dwFileAttributes = FileData.dwFileAttributes;
1136 pfad->ftCreationTime = FileData.ftCreationTime;
1137 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1138 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1139 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1140 pfad->nFileSizeLow = FileData.nFileSizeLow;
1141 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001142}
1143
Victor Stinnerd6f85422010-05-05 23:33:33 +00001144static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001145win32_stat(const char* path, struct win32_stat *result)
1146{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001147 WIN32_FILE_ATTRIBUTE_DATA info;
1148 int code;
1149 char *dot;
1150 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1151 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1152 /* Protocol violation: we explicitly clear errno, instead of
1153 setting it to a POSIX error. Callers should use GetLastError. */
1154 errno = 0;
1155 return -1;
1156 } else {
1157 /* Could not get attributes on open file. Fall back to
1158 reading the directory. */
1159 if (!attributes_from_dir(path, &info)) {
1160 /* Very strange. This should not fail now */
1161 errno = 0;
1162 return -1;
1163 }
1164 }
1165 }
1166 code = attribute_data_to_stat(&info, result);
1167 if (code != 0)
1168 return code;
1169 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1170 dot = strrchr(path, '.');
1171 if (dot) {
1172 if (stricmp(dot, ".bat") == 0 ||
1173 stricmp(dot, ".cmd") == 0 ||
1174 stricmp(dot, ".exe") == 0 ||
1175 stricmp(dot, ".com") == 0)
1176 result->st_mode |= 0111;
1177 }
1178 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001179}
1180
Victor Stinnerd6f85422010-05-05 23:33:33 +00001181static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001182win32_wstat(const wchar_t* path, struct win32_stat *result)
1183{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001184 int code;
1185 const wchar_t *dot;
1186 WIN32_FILE_ATTRIBUTE_DATA info;
1187 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1188 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1189 /* Protocol violation: we explicitly clear errno, instead of
1190 setting it to a POSIX error. Callers should use GetLastError. */
1191 errno = 0;
1192 return -1;
1193 } else {
1194 /* Could not get attributes on open file. Fall back to
1195 reading the directory. */
1196 if (!attributes_from_dir_w(path, &info)) {
1197 /* Very strange. This should not fail now */
1198 errno = 0;
1199 return -1;
1200 }
1201 }
1202 }
1203 code = attribute_data_to_stat(&info, result);
1204 if (code < 0)
1205 return code;
1206 /* Set IFEXEC if it is an .exe, .bat, ... */
1207 dot = wcsrchr(path, '.');
1208 if (dot) {
1209 if (_wcsicmp(dot, L".bat") == 0 ||
1210 _wcsicmp(dot, L".cmd") == 0 ||
1211 _wcsicmp(dot, L".exe") == 0 ||
1212 _wcsicmp(dot, L".com") == 0)
1213 result->st_mode |= 0111;
1214 }
1215 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001216}
1217
1218static int
1219win32_fstat(int file_number, struct win32_stat *result)
1220{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001221 BY_HANDLE_FILE_INFORMATION info;
1222 HANDLE h;
1223 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001224
Victor Stinnerd6f85422010-05-05 23:33:33 +00001225 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001226
Victor Stinnerd6f85422010-05-05 23:33:33 +00001227 /* Protocol violation: we explicitly clear errno, instead of
1228 setting it to a POSIX error. Callers should use GetLastError. */
1229 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001230
Victor Stinnerd6f85422010-05-05 23:33:33 +00001231 if (h == INVALID_HANDLE_VALUE) {
1232 /* This is really a C library error (invalid file handle).
1233 We set the Win32 error to the closes one matching. */
1234 SetLastError(ERROR_INVALID_HANDLE);
1235 return -1;
1236 }
1237 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001238
Victor Stinnerd6f85422010-05-05 23:33:33 +00001239 type = GetFileType(h);
1240 if (type == FILE_TYPE_UNKNOWN) {
1241 DWORD error = GetLastError();
1242 if (error != 0) {
1243 return -1;
1244 }
1245 /* else: valid but unknown file */
1246 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001247
Victor Stinnerd6f85422010-05-05 23:33:33 +00001248 if (type != FILE_TYPE_DISK) {
1249 if (type == FILE_TYPE_CHAR)
1250 result->st_mode = _S_IFCHR;
1251 else if (type == FILE_TYPE_PIPE)
1252 result->st_mode = _S_IFIFO;
1253 return 0;
1254 }
1255
1256 if (!GetFileInformationByHandle(h, &info)) {
1257 return -1;
1258 }
1259
1260 /* similar to stat() */
1261 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1262 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1263 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1264 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1265 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1266 /* specific to fstat() */
1267 result->st_nlink = info.nNumberOfLinks;
1268 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1269 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001270}
1271
1272#endif /* MS_WINDOWS */
1273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001274PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001275"stat_result: Result from stat or lstat.\n\n\
1276This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001277 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001278or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1279\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001280Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1281or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001282\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001283See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284
1285static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001286 {"st_mode", "protection bits"},
1287 {"st_ino", "inode"},
1288 {"st_dev", "device"},
1289 {"st_nlink", "number of hard links"},
1290 {"st_uid", "user ID of owner"},
1291 {"st_gid", "group ID of owner"},
1292 {"st_size", "total size, in bytes"},
1293 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1294 {NULL, "integer time of last access"},
1295 {NULL, "integer time of last modification"},
1296 {NULL, "integer time of last change"},
1297 {"st_atime", "time of last access"},
1298 {"st_mtime", "time of last modification"},
1299 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001300#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001301 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001302#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001303#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001304 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001305#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001306#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001308#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001309#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001310 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001311#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001312#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001313 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001314#endif
1315#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001316 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001317#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001318 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001319};
1320
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001321#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001322#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001323#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001324#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001325#endif
1326
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001327#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001328#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1329#else
1330#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1331#endif
1332
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001333#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1335#else
1336#define ST_RDEV_IDX ST_BLOCKS_IDX
1337#endif
1338
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001339#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1340#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1341#else
1342#define ST_FLAGS_IDX ST_RDEV_IDX
1343#endif
1344
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001345#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001346#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001347#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001348#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001349#endif
1350
1351#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1352#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1353#else
1354#define ST_BIRTHTIME_IDX ST_GEN_IDX
1355#endif
1356
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001357static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001358 "stat_result", /* name */
1359 stat_result__doc__, /* doc */
1360 stat_result_fields,
1361 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001362};
1363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001365"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1366This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001367 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001368or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001369\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001371
1372static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001373 {"f_bsize", },
1374 {"f_frsize", },
1375 {"f_blocks", },
1376 {"f_bfree", },
1377 {"f_bavail", },
1378 {"f_files", },
1379 {"f_ffree", },
1380 {"f_favail", },
1381 {"f_flag", },
1382 {"f_namemax",},
1383 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001384};
1385
1386static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001387 "statvfs_result", /* name */
1388 statvfs_result__doc__, /* doc */
1389 statvfs_result_fields,
1390 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001391};
1392
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001393static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001394static PyTypeObject StatResultType;
1395static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001396static newfunc structseq_new;
1397
1398static PyObject *
1399statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1400{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001401 PyStructSequence *result;
1402 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001403
Victor Stinnerd6f85422010-05-05 23:33:33 +00001404 result = (PyStructSequence*)structseq_new(type, args, kwds);
1405 if (!result)
1406 return NULL;
1407 /* If we have been initialized from a tuple,
1408 st_?time might be set to None. Initialize it
1409 from the int slots. */
1410 for (i = 7; i <= 9; i++) {
1411 if (result->ob_item[i+3] == Py_None) {
1412 Py_DECREF(Py_None);
1413 Py_INCREF(result->ob_item[i]);
1414 result->ob_item[i+3] = result->ob_item[i];
1415 }
1416 }
1417 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001418}
1419
1420
1421
1422/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001423static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001424
1425PyDoc_STRVAR(stat_float_times__doc__,
1426"stat_float_times([newval]) -> oldval\n\n\
1427Determine whether os.[lf]stat represents time stamps as float objects.\n\
1428If newval is True, future calls to stat() return floats, if it is False,\n\
1429future calls return ints. \n\
1430If newval is omitted, return the current setting.\n");
1431
1432static PyObject*
1433stat_float_times(PyObject* self, PyObject *args)
1434{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001435 int newval = -1;
1436 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1437 return NULL;
1438 if (newval == -1)
1439 /* Return old value */
1440 return PyBool_FromLong(_stat_float_times);
1441 _stat_float_times = newval;
1442 Py_INCREF(Py_None);
1443 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001444}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001445
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001446static void
1447fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1448{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001449 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001450#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001451 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001452#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001453 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001454#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001455 if (!ival)
1456 return;
1457 if (_stat_float_times) {
1458 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1459 } else {
1460 fval = ival;
1461 Py_INCREF(fval);
1462 }
1463 PyStructSequence_SET_ITEM(v, index, ival);
1464 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001465}
1466
Tim Peters5aa91602002-01-30 05:46:57 +00001467/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001468 (used by posix_stat() and posix_fstat()) */
1469static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001470_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001471{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001472 unsigned long ansec, mnsec, cnsec;
1473 PyObject *v = PyStructSequence_New(&StatResultType);
1474 if (v == NULL)
1475 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001476
Victor Stinnerd6f85422010-05-05 23:33:33 +00001477 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001478#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001479 PyStructSequence_SET_ITEM(v, 1,
1480 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001481#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001482 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001483#endif
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001484#ifdef MS_WINDOWS
1485 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001486#else
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001487 PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001488#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001489 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02001490#if defined(MS_WINDOWS)
1491 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
1492 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
1493#else
1494 PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
1495 PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
1496#endif
Fred Drake699f3522000-06-29 21:12:41 +00001497#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001498 PyStructSequence_SET_ITEM(v, 6,
1499 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001500#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001501 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001502#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001503
Martin v. Löwis14694662006-02-03 12:54:16 +00001504#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001505 ansec = st->st_atim.tv_nsec;
1506 mnsec = st->st_mtim.tv_nsec;
1507 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001508#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001509 ansec = st->st_atimespec.tv_nsec;
1510 mnsec = st->st_mtimespec.tv_nsec;
1511 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001512#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001513 ansec = st->st_atime_nsec;
1514 mnsec = st->st_mtime_nsec;
1515 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001516#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001517 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001518#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001519 fill_time(v, 7, st->st_atime, ansec);
1520 fill_time(v, 8, st->st_mtime, mnsec);
1521 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001522
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001523#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001524 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1525 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001526#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001527#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001528 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1529 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001530#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001531#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001532 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1533 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001534#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001535#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001536 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1537 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001538#endif
1539#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001540 {
1541 PyObject *val;
1542 unsigned long bsec,bnsec;
1543 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001544#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001545 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001546#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001547 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001548#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001549 if (_stat_float_times) {
1550 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1551 } else {
1552 val = PyInt_FromLong((long)bsec);
1553 }
1554 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1555 val);
1556 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001557#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001558#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001559 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1560 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001561#endif
Fred Drake699f3522000-06-29 21:12:41 +00001562
Victor Stinnerd6f85422010-05-05 23:33:33 +00001563 if (PyErr_Occurred()) {
1564 Py_DECREF(v);
1565 return NULL;
1566 }
Fred Drake699f3522000-06-29 21:12:41 +00001567
Victor Stinnerd6f85422010-05-05 23:33:33 +00001568 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001569}
1570
Martin v. Löwisd8948722004-06-02 09:57:56 +00001571#ifdef MS_WINDOWS
1572
1573/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1574 where / can be used in place of \ and the trailing slash is optional.
1575 Both SERVER and SHARE must have at least one character.
1576*/
1577
1578#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1579#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001580#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001581#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001582#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001583
Tim Peters4ad82172004-08-30 17:02:04 +00001584static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001585IsUNCRootA(char *path, int pathlen)
1586{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001587 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001588
Victor Stinnerd6f85422010-05-05 23:33:33 +00001589 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001590
Victor Stinnerd6f85422010-05-05 23:33:33 +00001591 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1592 /* minimum UNCRoot is \\x\y */
1593 return FALSE;
1594 for (i = 2; i < pathlen ; i++)
1595 if (ISSLASH(path[i])) break;
1596 if (i == 2 || i == pathlen)
1597 /* do not allow \\\SHARE or \\SERVER */
1598 return FALSE;
1599 share = i+1;
1600 for (i = share; i < pathlen; i++)
1601 if (ISSLASH(path[i])) break;
1602 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001603
Victor Stinnerd6f85422010-05-05 23:33:33 +00001604 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001605}
1606
Tim Peters4ad82172004-08-30 17:02:04 +00001607static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001608IsUNCRootW(Py_UNICODE *path, int pathlen)
1609{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001610 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001611
Victor Stinnerd6f85422010-05-05 23:33:33 +00001612 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001613
Victor Stinnerd6f85422010-05-05 23:33:33 +00001614 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1615 /* minimum UNCRoot is \\x\y */
1616 return FALSE;
1617 for (i = 2; i < pathlen ; i++)
1618 if (ISSLASH(path[i])) break;
1619 if (i == 2 || i == pathlen)
1620 /* do not allow \\\SHARE or \\SERVER */
1621 return FALSE;
1622 share = i+1;
1623 for (i = share; i < pathlen; i++)
1624 if (ISSLASH(path[i])) break;
1625 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001626
Victor Stinnerd6f85422010-05-05 23:33:33 +00001627 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001628}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001629#endif /* MS_WINDOWS */
1630
Barry Warsaw53699e91996-12-10 23:23:01 +00001631static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001632posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001633 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001634#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001635 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001636#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001637 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001638#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001639 char *wformat,
1640 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 STRUCT_STAT st;
1643 char *path = NULL; /* pass this to stat; do not free() it */
1644 char *pathfree = NULL; /* this memory must be free'd */
1645 int res;
1646 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001648#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001649 Py_UNICODE *wpath;
1650 if (PyArg_ParseTuple(args, wformat, &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001651 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001652 res = wstatfunc(wpath, &st);
1653 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001654
Victor Stinnerd6f85422010-05-05 23:33:33 +00001655 if (res != 0)
1656 return win32_error_unicode("stat", wpath);
1657 return _pystat_fromstructstat(&st);
1658 }
1659 /* Drop the argument parsing error as narrow strings
1660 are also valid. */
1661 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001662#endif
1663
Victor Stinnerd6f85422010-05-05 23:33:33 +00001664 if (!PyArg_ParseTuple(args, format,
1665 Py_FileSystemDefaultEncoding, &path))
1666 return NULL;
1667 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001668
Victor Stinnerd6f85422010-05-05 23:33:33 +00001669 Py_BEGIN_ALLOW_THREADS
1670 res = (*statfunc)(path, &st);
1671 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001672
Victor Stinnerd6f85422010-05-05 23:33:33 +00001673 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001674#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001675 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001676#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001677 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001678#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001679 }
1680 else
1681 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001682
Victor Stinnerd6f85422010-05-05 23:33:33 +00001683 PyMem_Free(pathfree);
1684 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001685}
1686
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001687/* POSIX methods */
1688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001689PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001690"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001691Use the real uid/gid to test for access to a path. Note that most\n\
1692operations will use the effective uid/gid, therefore this routine can\n\
1693be used in a suid/sgid environment to test if the invoking user has the\n\
1694specified access to the path. The mode argument can be F_OK to test\n\
1695existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001696
1697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001698posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001699{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001700 char *path;
1701 int mode;
1702
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001703#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001704 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001705 Py_UNICODE *wpath;
1706 if (PyArg_ParseTuple(args, "ui:access", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001707 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001708 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001709 Py_END_ALLOW_THREADS
1710 goto finish;
1711 }
1712 /* Drop the argument parsing error as narrow strings
1713 are also valid. */
1714 PyErr_Clear();
1715 if (!PyArg_ParseTuple(args, "eti:access",
1716 Py_FileSystemDefaultEncoding, &path, &mode))
1717 return NULL;
1718 Py_BEGIN_ALLOW_THREADS
1719 attr = GetFileAttributesA(path);
1720 Py_END_ALLOW_THREADS
1721 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001722finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001723 if (attr == 0xFFFFFFFF)
1724 /* File does not exist, or cannot read attributes */
1725 return PyBool_FromLong(0);
1726 /* Access is possible if either write access wasn't requested, or
1727 the file isn't read-only, or if it's a directory, as there are
1728 no read-only directories on Windows. */
1729 return PyBool_FromLong(!(mode & 2)
1730 || !(attr & FILE_ATTRIBUTE_READONLY)
1731 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001732#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001733 int res;
1734 if (!PyArg_ParseTuple(args, "eti:access",
1735 Py_FileSystemDefaultEncoding, &path, &mode))
1736 return NULL;
1737 Py_BEGIN_ALLOW_THREADS
1738 res = access(path, mode);
1739 Py_END_ALLOW_THREADS
1740 PyMem_Free(path);
1741 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001742#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001743}
1744
Guido van Rossumd371ff11999-01-25 16:12:23 +00001745#ifndef F_OK
1746#define F_OK 0
1747#endif
1748#ifndef R_OK
1749#define R_OK 4
1750#endif
1751#ifndef W_OK
1752#define W_OK 2
1753#endif
1754#ifndef X_OK
1755#define X_OK 1
1756#endif
1757
1758#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001759PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001760"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001762
1763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001764posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001766 int id;
1767 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001768
Victor Stinnerd6f85422010-05-05 23:33:33 +00001769 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1770 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001772#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001773 /* file descriptor 0 only, the default input device (stdin) */
1774 if (id == 0) {
1775 ret = ttyname();
1776 }
1777 else {
1778 ret = NULL;
1779 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001780#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001781 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001782#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001783 if (ret == NULL)
1784 return posix_error();
1785 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001786}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001787#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001788
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001789#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001790PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001791"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001793
1794static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001795posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001796{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001797 char *ret;
1798 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799
Greg Wardb48bc172000-03-01 21:51:56 +00001800#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001801 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001803 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001805 if (ret == NULL)
1806 return posix_error();
1807 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808}
1809#endif
1810
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001812"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001814
Barry Warsaw53699e91996-12-10 23:23:01 +00001815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001817{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001818#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001819 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001820#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001821 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001822#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001823 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001824#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001825 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001826#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001827}
1828
Fred Drake4d1e64b2002-04-15 19:40:07 +00001829#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001830PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001831"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001832Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001834
1835static PyObject *
1836posix_fchdir(PyObject *self, PyObject *fdobj)
1837{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001838 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001839}
1840#endif /* HAVE_FCHDIR */
1841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001843PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001844"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001845Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001846
Barry Warsaw53699e91996-12-10 23:23:01 +00001847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001848posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001850 char *path = NULL;
1851 int i;
1852 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001853#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001854 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001855 Py_UNICODE *wpath;
1856 if (PyArg_ParseTuple(args, "ui|:chmod", &wpath, &i)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001857 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001858 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001859 if (attr != 0xFFFFFFFF) {
1860 if (i & _S_IWRITE)
1861 attr &= ~FILE_ATTRIBUTE_READONLY;
1862 else
1863 attr |= FILE_ATTRIBUTE_READONLY;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001864 res = SetFileAttributesW(wpath, attr);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001865 }
1866 else
1867 res = 0;
1868 Py_END_ALLOW_THREADS
1869 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001870 return win32_error_unicode("chmod", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001871 Py_INCREF(Py_None);
1872 return Py_None;
1873 }
1874 /* Drop the argument parsing error as narrow strings
1875 are also valid. */
1876 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001877
Victor Stinnerd6f85422010-05-05 23:33:33 +00001878 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1879 &path, &i))
1880 return NULL;
1881 Py_BEGIN_ALLOW_THREADS
1882 attr = GetFileAttributesA(path);
1883 if (attr != 0xFFFFFFFF) {
1884 if (i & _S_IWRITE)
1885 attr &= ~FILE_ATTRIBUTE_READONLY;
1886 else
1887 attr |= FILE_ATTRIBUTE_READONLY;
1888 res = SetFileAttributesA(path, attr);
1889 }
1890 else
1891 res = 0;
1892 Py_END_ALLOW_THREADS
1893 if (!res) {
1894 win32_error("chmod", path);
1895 PyMem_Free(path);
1896 return NULL;
1897 }
1898 PyMem_Free(path);
1899 Py_INCREF(Py_None);
1900 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001901#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001902 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1903 &path, &i))
1904 return NULL;
1905 Py_BEGIN_ALLOW_THREADS
1906 res = chmod(path, i);
1907 Py_END_ALLOW_THREADS
1908 if (res < 0)
1909 return posix_error_with_allocated_filename(path);
1910 PyMem_Free(path);
1911 Py_INCREF(Py_None);
1912 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001913#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001914}
1915
Christian Heimes36281872007-11-30 21:11:28 +00001916#ifdef HAVE_FCHMOD
1917PyDoc_STRVAR(posix_fchmod__doc__,
1918"fchmod(fd, mode)\n\n\
1919Change the access permissions of the file given by file\n\
1920descriptor fd.");
1921
1922static PyObject *
1923posix_fchmod(PyObject *self, PyObject *args)
1924{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001925 int fd, mode, res;
1926 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1927 return NULL;
1928 Py_BEGIN_ALLOW_THREADS
1929 res = fchmod(fd, mode);
1930 Py_END_ALLOW_THREADS
1931 if (res < 0)
1932 return posix_error();
1933 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001934}
1935#endif /* HAVE_FCHMOD */
1936
1937#ifdef HAVE_LCHMOD
1938PyDoc_STRVAR(posix_lchmod__doc__,
1939"lchmod(path, mode)\n\n\
1940Change the access permissions of a file. If path is a symlink, this\n\
1941affects the link itself rather than the target.");
1942
1943static PyObject *
1944posix_lchmod(PyObject *self, PyObject *args)
1945{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001946 char *path = NULL;
1947 int i;
1948 int res;
1949 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1950 &path, &i))
1951 return NULL;
1952 Py_BEGIN_ALLOW_THREADS
1953 res = lchmod(path, i);
1954 Py_END_ALLOW_THREADS
1955 if (res < 0)
1956 return posix_error_with_allocated_filename(path);
1957 PyMem_Free(path);
1958 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001959}
1960#endif /* HAVE_LCHMOD */
1961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001962
Martin v. Löwis382abef2007-02-19 10:55:19 +00001963#ifdef HAVE_CHFLAGS
1964PyDoc_STRVAR(posix_chflags__doc__,
1965"chflags(path, flags)\n\n\
1966Set file flags.");
1967
1968static PyObject *
1969posix_chflags(PyObject *self, PyObject *args)
1970{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001971 char *path;
1972 unsigned long flags;
1973 int res;
1974 if (!PyArg_ParseTuple(args, "etk:chflags",
1975 Py_FileSystemDefaultEncoding, &path, &flags))
1976 return NULL;
1977 Py_BEGIN_ALLOW_THREADS
1978 res = chflags(path, flags);
1979 Py_END_ALLOW_THREADS
1980 if (res < 0)
1981 return posix_error_with_allocated_filename(path);
1982 PyMem_Free(path);
1983 Py_INCREF(Py_None);
1984 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001985}
1986#endif /* HAVE_CHFLAGS */
1987
1988#ifdef HAVE_LCHFLAGS
1989PyDoc_STRVAR(posix_lchflags__doc__,
1990"lchflags(path, flags)\n\n\
1991Set file flags.\n\
1992This function will not follow symbolic links.");
1993
1994static PyObject *
1995posix_lchflags(PyObject *self, PyObject *args)
1996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001997 char *path;
1998 unsigned long flags;
1999 int res;
2000 if (!PyArg_ParseTuple(args, "etk:lchflags",
2001 Py_FileSystemDefaultEncoding, &path, &flags))
2002 return NULL;
2003 Py_BEGIN_ALLOW_THREADS
2004 res = lchflags(path, flags);
2005 Py_END_ALLOW_THREADS
2006 if (res < 0)
2007 return posix_error_with_allocated_filename(path);
2008 PyMem_Free(path);
2009 Py_INCREF(Py_None);
2010 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00002011}
2012#endif /* HAVE_LCHFLAGS */
2013
Martin v. Löwis244edc82001-10-04 22:44:26 +00002014#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002015PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002016"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002017Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002018
2019static PyObject *
2020posix_chroot(PyObject *self, PyObject *args)
2021{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002022 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002023}
2024#endif
2025
Guido van Rossum21142a01999-01-08 21:05:37 +00002026#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002027PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002028"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002030
2031static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002032posix_fsync(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, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002035}
2036#endif /* HAVE_FSYNC */
2037
2038#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002039
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002040#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002041extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2042#endif
2043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002045"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002046force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002048
2049static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002050posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002051{
Stefan Krah93f7a322010-11-26 17:35:50 +00002052 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002053}
2054#endif /* HAVE_FDATASYNC */
2055
2056
Fredrik Lundh10723342000-07-10 16:38:09 +00002057#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002059"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002060Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Barry Warsaw53699e91996-12-10 23:23:01 +00002062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002063posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002064{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002065 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002066 uid_t uid;
2067 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002068 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002069 if (!PyArg_ParseTuple(args, "etO&O&:chown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002070 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002071 _Py_Uid_Converter, &uid,
2072 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002073 return NULL;
2074 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002075 res = chown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002076 Py_END_ALLOW_THREADS
2077 if (res < 0)
2078 return posix_error_with_allocated_filename(path);
2079 PyMem_Free(path);
2080 Py_INCREF(Py_None);
2081 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002083#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002084
Christian Heimes36281872007-11-30 21:11:28 +00002085#ifdef HAVE_FCHOWN
2086PyDoc_STRVAR(posix_fchown__doc__,
2087"fchown(fd, uid, gid)\n\n\
2088Change the owner and group id of the file given by file descriptor\n\
2089fd to the numeric uid and gid.");
2090
2091static PyObject *
2092posix_fchown(PyObject *self, PyObject *args)
2093{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002094 int fd;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002095 uid_t uid;
2096 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002097 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002098 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
2099 _Py_Uid_Converter, &uid,
2100 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002101 return NULL;
2102 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002103 res = fchown(fd, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002104 Py_END_ALLOW_THREADS
2105 if (res < 0)
2106 return posix_error();
2107 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00002108}
2109#endif /* HAVE_FCHOWN */
2110
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002111#ifdef HAVE_LCHOWN
2112PyDoc_STRVAR(posix_lchown__doc__,
2113"lchown(path, uid, gid)\n\n\
2114Change the owner and group id of path to the numeric uid and gid.\n\
2115This function will not follow symbolic links.");
2116
2117static PyObject *
2118posix_lchown(PyObject *self, PyObject *args)
2119{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002120 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002121 uid_t uid;
2122 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002123 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002124 if (!PyArg_ParseTuple(args, "etO&O&:lchown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002125 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002126 _Py_Uid_Converter, &uid,
2127 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002128 return NULL;
2129 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002130 res = lchown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002131 Py_END_ALLOW_THREADS
2132 if (res < 0)
2133 return posix_error_with_allocated_filename(path);
2134 PyMem_Free(path);
2135 Py_INCREF(Py_None);
2136 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002137}
2138#endif /* HAVE_LCHOWN */
2139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002140
Guido van Rossum36bc6801995-06-14 22:54:23 +00002141#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002144Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145
Trent Nelsonda4277a2012-08-29 09:20:41 -04002146#if (defined(__sun) && defined(__SVR4)) || \
2147 defined(__OpenBSD__) || \
2148 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00002149/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
2150static PyObject *
2151posix_getcwd(PyObject *self, PyObject *noargs)
2152{
2153 char buf[PATH_MAX+2];
2154 char *res;
2155
2156 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00002157 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00002158 Py_END_ALLOW_THREADS
2159
2160 if (res == NULL)
2161 return posix_error();
2162
2163 return PyString_FromString(buf);
2164}
2165#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002166static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002167posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002168{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002169 int bufsize_incr = 1024;
2170 int bufsize = 0;
2171 char *tmpbuf = NULL;
2172 char *res = NULL;
2173 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002174
Victor Stinnerd6f85422010-05-05 23:33:33 +00002175 Py_BEGIN_ALLOW_THREADS
2176 do {
2177 bufsize = bufsize + bufsize_incr;
2178 tmpbuf = malloc(bufsize);
2179 if (tmpbuf == NULL) {
2180 break;
2181 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002182#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002183 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002184#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002185 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002186#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002187
Victor Stinnerd6f85422010-05-05 23:33:33 +00002188 if (res == NULL) {
2189 free(tmpbuf);
2190 }
2191 } while ((res == NULL) && (errno == ERANGE));
2192 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002193
Victor Stinnerd6f85422010-05-05 23:33:33 +00002194 if (res == NULL)
2195 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002196
Victor Stinnerd6f85422010-05-05 23:33:33 +00002197 dynamic_return = PyString_FromString(tmpbuf);
2198 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002199
Victor Stinnerd6f85422010-05-05 23:33:33 +00002200 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002201}
Stefan Krah182ae642010-07-13 19:17:08 +00002202#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002203
Walter Dörwald3b918c32002-11-21 20:18:46 +00002204#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002205PyDoc_STRVAR(posix_getcwdu__doc__,
2206"getcwdu() -> path\n\n\
2207Return a unicode string representing the current working directory.");
2208
2209static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002210posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002211{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002212 char buf[1026];
2213 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002214
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002215#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002216 DWORD len;
2217 wchar_t wbuf[1026];
2218 wchar_t *wbuf2 = wbuf;
2219 PyObject *resobj;
2220 Py_BEGIN_ALLOW_THREADS
2221 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2222 /* If the buffer is large enough, len does not include the
2223 terminating \0. If the buffer is too small, len includes
2224 the space needed for the terminator. */
2225 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2226 wbuf2 = malloc(len * sizeof(wchar_t));
2227 if (wbuf2)
2228 len = GetCurrentDirectoryW(len, wbuf2);
2229 }
2230 Py_END_ALLOW_THREADS
2231 if (!wbuf2) {
2232 PyErr_NoMemory();
2233 return NULL;
2234 }
2235 if (!len) {
2236 if (wbuf2 != wbuf) free(wbuf2);
2237 return win32_error("getcwdu", NULL);
2238 }
2239 resobj = PyUnicode_FromWideChar(wbuf2, len);
2240 if (wbuf2 != wbuf) free(wbuf2);
2241 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002242#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002243
Victor Stinnerd6f85422010-05-05 23:33:33 +00002244 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002245#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002246 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002247#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002248 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002250 Py_END_ALLOW_THREADS
2251 if (res == NULL)
2252 return posix_error();
2253 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002254}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002255#endif /* Py_USING_UNICODE */
2256#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002258
Guido van Rossumb6775db1994-08-01 11:34:53 +00002259#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002260PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002261"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002262Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002263
Barry Warsaw53699e91996-12-10 23:23:01 +00002264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002265posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002266{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002267 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002268}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002269#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002271
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002272PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002273"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002274Return a list containing the names of the entries in the directory.\n\
2275\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002276 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002277\n\
2278The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002280
Barry Warsaw53699e91996-12-10 23:23:01 +00002281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002282posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002283{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002284 /* XXX Should redo this putting the (now four) versions of opendir
2285 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002286#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002287
Victor Stinnerd6f85422010-05-05 23:33:33 +00002288 PyObject *d, *v;
2289 HANDLE hFindFile;
2290 BOOL result;
2291 WIN32_FIND_DATA FileData;
2292 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2293 char *bufptr = namebuf;
2294 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002295
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002296 Py_UNICODE *wpath;
2297 if (PyArg_ParseTuple(args, "u:listdir", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002298 WIN32_FIND_DATAW wFileData;
2299 Py_UNICODE *wnamebuf;
2300 /* Overallocate for \\*.*\0 */
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002301 len = wcslen(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002302 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2303 if (!wnamebuf) {
2304 PyErr_NoMemory();
2305 return NULL;
2306 }
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002307 wcscpy(wnamebuf, wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002308 if (len > 0) {
2309 Py_UNICODE wch = wnamebuf[len-1];
2310 if (wch != L'/' && wch != L'\\' && wch != L':')
2311 wnamebuf[len++] = L'\\';
2312 wcscpy(wnamebuf + len, L"*.*");
2313 }
2314 if ((d = PyList_New(0)) == NULL) {
2315 free(wnamebuf);
2316 return NULL;
2317 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002318 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002319 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002320 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002321 if (hFindFile == INVALID_HANDLE_VALUE) {
2322 int error = GetLastError();
2323 if (error == ERROR_FILE_NOT_FOUND) {
2324 free(wnamebuf);
2325 return d;
2326 }
2327 Py_DECREF(d);
2328 win32_error_unicode("FindFirstFileW", wnamebuf);
2329 free(wnamebuf);
2330 return NULL;
2331 }
2332 do {
2333 /* Skip over . and .. */
2334 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2335 wcscmp(wFileData.cFileName, L"..") != 0) {
2336 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2337 if (v == NULL) {
2338 Py_DECREF(d);
2339 d = NULL;
2340 break;
2341 }
2342 if (PyList_Append(d, v) != 0) {
2343 Py_DECREF(v);
2344 Py_DECREF(d);
2345 d = NULL;
2346 break;
2347 }
2348 Py_DECREF(v);
2349 }
2350 Py_BEGIN_ALLOW_THREADS
2351 result = FindNextFileW(hFindFile, &wFileData);
2352 Py_END_ALLOW_THREADS
2353 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2354 it got to the end of the directory. */
2355 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2356 Py_DECREF(d);
2357 win32_error_unicode("FindNextFileW", wnamebuf);
2358 FindClose(hFindFile);
2359 free(wnamebuf);
2360 return NULL;
2361 }
2362 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002363
Victor Stinnerd6f85422010-05-05 23:33:33 +00002364 if (FindClose(hFindFile) == FALSE) {
2365 Py_DECREF(d);
2366 win32_error_unicode("FindClose", wnamebuf);
2367 free(wnamebuf);
2368 return NULL;
2369 }
2370 free(wnamebuf);
2371 return d;
2372 }
2373 /* Drop the argument parsing error as narrow strings
2374 are also valid. */
2375 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002376
Victor Stinnerd6f85422010-05-05 23:33:33 +00002377 if (!PyArg_ParseTuple(args, "et#:listdir",
2378 Py_FileSystemDefaultEncoding, &bufptr, &len))
2379 return NULL;
2380 if (len > 0) {
2381 char ch = namebuf[len-1];
2382 if (ch != SEP && ch != ALTSEP && ch != ':')
2383 namebuf[len++] = '/';
2384 strcpy(namebuf + len, "*.*");
2385 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002386
Victor Stinnerd6f85422010-05-05 23:33:33 +00002387 if ((d = PyList_New(0)) == NULL)
2388 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002389
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002390 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002391 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002392 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002393 if (hFindFile == INVALID_HANDLE_VALUE) {
2394 int error = GetLastError();
2395 if (error == ERROR_FILE_NOT_FOUND)
2396 return d;
2397 Py_DECREF(d);
2398 return win32_error("FindFirstFile", namebuf);
2399 }
2400 do {
2401 /* Skip over . and .. */
2402 if (strcmp(FileData.cFileName, ".") != 0 &&
2403 strcmp(FileData.cFileName, "..") != 0) {
2404 v = PyString_FromString(FileData.cFileName);
2405 if (v == NULL) {
2406 Py_DECREF(d);
2407 d = NULL;
2408 break;
2409 }
2410 if (PyList_Append(d, v) != 0) {
2411 Py_DECREF(v);
2412 Py_DECREF(d);
2413 d = NULL;
2414 break;
2415 }
2416 Py_DECREF(v);
2417 }
2418 Py_BEGIN_ALLOW_THREADS
2419 result = FindNextFile(hFindFile, &FileData);
2420 Py_END_ALLOW_THREADS
2421 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2422 it got to the end of the directory. */
2423 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2424 Py_DECREF(d);
2425 win32_error("FindNextFile", namebuf);
2426 FindClose(hFindFile);
2427 return NULL;
2428 }
2429 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002430
Victor Stinnerd6f85422010-05-05 23:33:33 +00002431 if (FindClose(hFindFile) == FALSE) {
2432 Py_DECREF(d);
2433 return win32_error("FindClose", namebuf);
2434 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002435
Victor Stinnerd6f85422010-05-05 23:33:33 +00002436 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002437
Tim Peters0bb44a42000-09-15 07:44:49 +00002438#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439
2440#ifndef MAX_PATH
2441#define MAX_PATH CCHMAXPATH
2442#endif
2443 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002444 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002445 PyObject *d, *v;
2446 char namebuf[MAX_PATH+5];
2447 HDIR hdir = 1;
2448 ULONG srchcnt = 1;
2449 FILEFINDBUF3 ep;
2450 APIRET rc;
2451
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002452 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002453 return NULL;
2454 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002455 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002456 return NULL;
2457 }
2458 strcpy(namebuf, name);
2459 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002460 if (*pt == ALTSEP)
2461 *pt = SEP;
2462 if (namebuf[len-1] != SEP)
2463 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002464 strcpy(namebuf + len, "*.*");
2465
Victor Stinnerd6f85422010-05-05 23:33:33 +00002466 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002467 return NULL;
2468
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002469 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2470 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002471 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002472 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2473 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2474 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002475
2476 if (rc != NO_ERROR) {
2477 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002478 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002479 }
2480
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002481 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002482 do {
2483 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002484 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002485 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002486
2487 strcpy(namebuf, ep.achName);
2488
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002489 /* Leave Case of Name Alone -- In Native Form */
2490 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002491
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002492 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002493 if (v == NULL) {
2494 Py_DECREF(d);
2495 d = NULL;
2496 break;
2497 }
2498 if (PyList_Append(d, v) != 0) {
2499 Py_DECREF(v);
2500 Py_DECREF(d);
2501 d = NULL;
2502 break;
2503 }
2504 Py_DECREF(v);
2505 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2506 }
2507
2508 return d;
2509#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002510
Victor Stinnerd6f85422010-05-05 23:33:33 +00002511 char *name = NULL;
2512 PyObject *d, *v;
2513 DIR *dirp;
2514 struct dirent *ep;
2515 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002516
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 errno = 0;
2518 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2519 arg_is_unicode = 0;
2520 PyErr_Clear();
2521 }
2522 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2523 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002524 Py_BEGIN_ALLOW_THREADS
2525 dirp = opendir(name);
2526 Py_END_ALLOW_THREADS
2527 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002528 return posix_error_with_allocated_filename(name);
2529 }
2530 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002531 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002532 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002533 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002534 PyMem_Free(name);
2535 return NULL;
2536 }
2537 for (;;) {
2538 errno = 0;
2539 Py_BEGIN_ALLOW_THREADS
2540 ep = readdir(dirp);
2541 Py_END_ALLOW_THREADS
2542 if (ep == NULL) {
2543 if (errno == 0) {
2544 break;
2545 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002546 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002547 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002548 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002549 Py_DECREF(d);
2550 return posix_error_with_allocated_filename(name);
2551 }
2552 }
2553 if (ep->d_name[0] == '.' &&
2554 (NAMLEN(ep) == 1 ||
2555 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2556 continue;
2557 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2558 if (v == NULL) {
2559 Py_DECREF(d);
2560 d = NULL;
2561 break;
2562 }
Just van Rossum46c97842003-02-25 21:42:15 +00002563#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002564 if (arg_is_unicode) {
2565 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002566
Victor Stinnerd6f85422010-05-05 23:33:33 +00002567 w = PyUnicode_FromEncodedObject(v,
2568 Py_FileSystemDefaultEncoding,
2569 "strict");
2570 if (w != NULL) {
2571 Py_DECREF(v);
2572 v = w;
2573 }
2574 else {
2575 /* fall back to the original byte string, as
2576 discussed in patch #683592 */
2577 PyErr_Clear();
2578 }
2579 }
Just van Rossum46c97842003-02-25 21:42:15 +00002580#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002581 if (PyList_Append(d, v) != 0) {
2582 Py_DECREF(v);
2583 Py_DECREF(d);
2584 d = NULL;
2585 break;
2586 }
2587 Py_DECREF(v);
2588 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002589 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002590 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002591 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002592 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002593
Victor Stinnerd6f85422010-05-05 23:33:33 +00002594 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002595
Tim Peters0bb44a42000-09-15 07:44:49 +00002596#endif /* which OS */
2597} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002598
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002599#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002600/* A helper function for abspath on win32 */
2601static PyObject *
2602posix__getfullpathname(PyObject *self, PyObject *args)
2603{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002604 /* assume encoded strings won't more than double no of chars */
2605 char inbuf[MAX_PATH*2];
2606 char *inbufp = inbuf;
2607 Py_ssize_t insize = sizeof(inbuf);
2608 char outbuf[MAX_PATH*2];
2609 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002610
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002611 Py_UNICODE *wpath;
2612 if (PyArg_ParseTuple(args, "u|:_getfullpathname", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002613 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2614 Py_UNICODE *wtemp;
2615 DWORD result;
2616 PyObject *v;
2617 result = GetFullPathNameW(wpath,
2618 sizeof(woutbuf)/sizeof(woutbuf[0]),
2619 woutbuf, &wtemp);
2620 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2621 woutbufp = malloc(result * sizeof(Py_UNICODE));
2622 if (!woutbufp)
2623 return PyErr_NoMemory();
2624 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2625 }
2626 if (result)
2627 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2628 else
2629 v = win32_error_unicode("GetFullPathNameW", wpath);
2630 if (woutbufp != woutbuf)
2631 free(woutbufp);
2632 return v;
2633 }
2634 /* Drop the argument parsing error as narrow strings
2635 are also valid. */
2636 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002637
Victor Stinnerd6f85422010-05-05 23:33:33 +00002638 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2639 Py_FileSystemDefaultEncoding, &inbufp,
2640 &insize))
2641 return NULL;
2642 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2643 outbuf, &temp))
2644 return win32_error("GetFullPathName", inbuf);
2645 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2646 return PyUnicode_Decode(outbuf, strlen(outbuf),
2647 Py_FileSystemDefaultEncoding, NULL);
2648 }
2649 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002650} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002651#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002652
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002653PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002654"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002656
Barry Warsaw53699e91996-12-10 23:23:01 +00002657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002658posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002659{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002660 int res;
2661 char *path = NULL;
2662 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002663
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002664#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002665 Py_UNICODE *wpath;
2666 if (PyArg_ParseTuple(args, "u|i:mkdir", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002667 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002668 res = CreateDirectoryW(wpath, NULL);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002669 Py_END_ALLOW_THREADS
2670 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002671 return win32_error_unicode("mkdir", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002672 Py_INCREF(Py_None);
2673 return Py_None;
2674 }
2675 /* Drop the argument parsing error as narrow strings
2676 are also valid. */
2677 PyErr_Clear();
2678 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2679 Py_FileSystemDefaultEncoding, &path, &mode))
2680 return NULL;
2681 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002682 res = CreateDirectoryA(path, NULL);
2683 Py_END_ALLOW_THREADS
2684 if (!res) {
2685 win32_error("mkdir", path);
2686 PyMem_Free(path);
2687 return NULL;
2688 }
2689 PyMem_Free(path);
2690 Py_INCREF(Py_None);
2691 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002692#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002693
Victor Stinnerd6f85422010-05-05 23:33:33 +00002694 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2695 Py_FileSystemDefaultEncoding, &path, &mode))
2696 return NULL;
2697 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002698#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002699 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002700#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002701 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002702#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002703 Py_END_ALLOW_THREADS
2704 if (res < 0)
2705 return posix_error_with_allocated_filename(path);
2706 PyMem_Free(path);
2707 Py_INCREF(Py_None);
2708 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002709#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002710}
2711
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002712
Neal Norwitz1818ed72006-03-26 00:29:48 +00002713/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2714#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002715#include <sys/resource.h>
2716#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002717
Neal Norwitz1818ed72006-03-26 00:29:48 +00002718
2719#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002720PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002721"nice(inc) -> new_priority\n\n\
2722Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002723
Barry Warsaw53699e91996-12-10 23:23:01 +00002724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002725posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002726{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002727 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002728
Victor Stinnerd6f85422010-05-05 23:33:33 +00002729 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2730 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002731
Victor Stinnerd6f85422010-05-05 23:33:33 +00002732 /* There are two flavours of 'nice': one that returns the new
2733 priority (as required by almost all standards out there) and the
2734 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2735 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002736
Victor Stinnerd6f85422010-05-05 23:33:33 +00002737 If we are of the nice family that returns the new priority, we
2738 need to clear errno before the call, and check if errno is filled
2739 before calling posix_error() on a returnvalue of -1, because the
2740 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002741
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 errno = 0;
2743 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002744#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002745 if (value == 0)
2746 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002747#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002748 if (value == -1 && errno != 0)
2749 /* either nice() or getpriority() returned an error */
2750 return posix_error();
2751 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002752}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002753#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002754
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002755PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002756"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002757Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002758
Barry Warsaw53699e91996-12-10 23:23:01 +00002759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002760posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002761{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002762#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002763 PyObject *o1, *o2;
2764 char *p1, *p2;
2765 BOOL result;
2766 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2767 goto error;
2768 if (!convert_to_unicode(&o1))
2769 goto error;
2770 if (!convert_to_unicode(&o2)) {
2771 Py_DECREF(o1);
2772 goto error;
2773 }
2774 Py_BEGIN_ALLOW_THREADS
2775 result = MoveFileW(PyUnicode_AsUnicode(o1),
2776 PyUnicode_AsUnicode(o2));
2777 Py_END_ALLOW_THREADS
2778 Py_DECREF(o1);
2779 Py_DECREF(o2);
2780 if (!result)
2781 return win32_error("rename", NULL);
2782 Py_INCREF(Py_None);
2783 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002784error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002785 PyErr_Clear();
2786 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2787 return NULL;
2788 Py_BEGIN_ALLOW_THREADS
2789 result = MoveFileA(p1, p2);
2790 Py_END_ALLOW_THREADS
2791 if (!result)
2792 return win32_error("rename", NULL);
2793 Py_INCREF(Py_None);
2794 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002795#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002796 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002797#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002798}
2799
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002800
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002801PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002802"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002803Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002804
Barry Warsaw53699e91996-12-10 23:23:01 +00002805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002806posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002807{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002808#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002809 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002810#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002811 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002812#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002813}
2814
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002815
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002816PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002817"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002818Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002819
Barry Warsaw53699e91996-12-10 23:23:01 +00002820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002821posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002822{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002823#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002824 return posix_do_stat(self, args, "et:stat", STAT, "u:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002825#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002826 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002827#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002828}
2829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002830
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002831#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002832PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002833"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002834Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Barry Warsaw53699e91996-12-10 23:23:01 +00002836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002837posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002838{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002839 char *command;
2840 long sts;
2841 if (!PyArg_ParseTuple(args, "s:system", &command))
2842 return NULL;
2843 Py_BEGIN_ALLOW_THREADS
2844 sts = system(command);
2845 Py_END_ALLOW_THREADS
2846 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002847}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002848#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002850
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002852"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002853Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002854
Barry Warsaw53699e91996-12-10 23:23:01 +00002855static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002856posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002857{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002858 int i;
2859 if (!PyArg_ParseTuple(args, "i:umask", &i))
2860 return NULL;
2861 i = (int)umask(i);
2862 if (i < 0)
2863 return posix_error();
2864 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002865}
2866
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002867
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002868PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002869"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002870Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002871
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002872PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002873"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002874Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002875
Barry Warsaw53699e91996-12-10 23:23:01 +00002876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002877posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002878{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002879#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002880 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002881#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002882 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002883#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002884}
2885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002886
Guido van Rossumb6775db1994-08-01 11:34:53 +00002887#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002888PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002889"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002890Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002891
Barry Warsaw53699e91996-12-10 23:23:01 +00002892static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002893posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002894{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002895 struct utsname u;
2896 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002897
Victor Stinnerd6f85422010-05-05 23:33:33 +00002898 Py_BEGIN_ALLOW_THREADS
2899 res = uname(&u);
2900 Py_END_ALLOW_THREADS
2901 if (res < 0)
2902 return posix_error();
2903 return Py_BuildValue("(sssss)",
2904 u.sysname,
2905 u.nodename,
2906 u.release,
2907 u.version,
2908 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002909}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002910#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002911
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002912static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002913extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002914{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002915 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002916 if (PyFloat_Check(t)) {
2917 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002918 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002919 if (!intobj)
2920 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002921#if SIZEOF_TIME_T > SIZEOF_LONG
2922 intval = PyInt_AsUnsignedLongLongMask(intobj);
2923#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002924 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002925#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002926 Py_DECREF(intobj);
2927 if (intval == -1 && PyErr_Occurred())
2928 return -1;
2929 *sec = intval;
2930 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2931 if (*usec < 0)
2932 /* If rounding gave us a negative number,
2933 truncate. */
2934 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002935 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002936 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002937#if SIZEOF_TIME_T > SIZEOF_LONG
2938 intval = PyInt_AsUnsignedLongLongMask(t);
2939#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002940 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002941#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002942 if (intval == -1 && PyErr_Occurred())
2943 return -1;
2944 *sec = intval;
2945 *usec = 0;
2946 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002947}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002949PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002950"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002951utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002952Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002953second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002954
Barry Warsaw53699e91996-12-10 23:23:01 +00002955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002956posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002957{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002958#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002959 PyObject *arg;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002960 wchar_t *wpath = NULL;
2961 char *apath = NULL;
2962 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002963 time_t atimesec, mtimesec;
2964 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002965 FILETIME atime, mtime;
2966 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002967
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002968 if (PyArg_ParseTuple(args, "uO|:utime", &wpath, &arg)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002969 Py_BEGIN_ALLOW_THREADS
2970 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2971 NULL, OPEN_EXISTING,
2972 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2973 Py_END_ALLOW_THREADS
2974 if (hFile == INVALID_HANDLE_VALUE)
2975 return win32_error_unicode("utime", wpath);
2976 } else
2977 /* Drop the argument parsing error as narrow strings
2978 are also valid. */
2979 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002980
Victor Stinnerd6f85422010-05-05 23:33:33 +00002981 if (!wpath) {
2982 if (!PyArg_ParseTuple(args, "etO:utime",
2983 Py_FileSystemDefaultEncoding, &apath, &arg))
2984 return NULL;
2985 Py_BEGIN_ALLOW_THREADS
2986 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2987 NULL, OPEN_EXISTING,
2988 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2989 Py_END_ALLOW_THREADS
2990 if (hFile == INVALID_HANDLE_VALUE) {
2991 win32_error("utime", apath);
2992 PyMem_Free(apath);
2993 return NULL;
2994 }
2995 PyMem_Free(apath);
2996 }
2997
2998 if (arg == Py_None) {
2999 SYSTEMTIME now;
3000 GetSystemTime(&now);
3001 if (!SystemTimeToFileTime(&now, &mtime) ||
3002 !SystemTimeToFileTime(&now, &atime)) {
3003 win32_error("utime", NULL);
3004 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00003005 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003006 }
3007 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3008 PyErr_SetString(PyExc_TypeError,
3009 "utime() arg 2 must be a tuple (atime, mtime)");
3010 goto done;
3011 }
3012 else {
3013 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3014 &atimesec, &ausec) == -1)
3015 goto done;
3016 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3017 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3018 &mtimesec, &musec) == -1)
3019 goto done;
3020 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3021 }
3022 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3023 /* Avoid putting the file name into the error here,
3024 as that may confuse the user into believing that
3025 something is wrong with the file, when it also
3026 could be the time stamp that gives a problem. */
3027 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00003028 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003029 }
3030 Py_INCREF(Py_None);
3031 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003032done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003033 CloseHandle(hFile);
3034 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003035#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003036
Victor Stinnerd6f85422010-05-05 23:33:33 +00003037 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00003038 time_t atime, mtime;
3039 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003040 int res;
3041 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003042
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003043#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003044 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003045#define ATIME buf[0].tv_sec
3046#define MTIME buf[1].tv_sec
3047#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003048/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003049 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003050#define ATIME buf.actime
3051#define MTIME buf.modtime
3052#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003053#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003054 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003055#define ATIME buf[0]
3056#define MTIME buf[1]
3057#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003058#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003059
Mark Hammond817c9292003-12-03 01:22:38 +00003060
Victor Stinnerd6f85422010-05-05 23:33:33 +00003061 if (!PyArg_ParseTuple(args, "etO:utime",
3062 Py_FileSystemDefaultEncoding, &path, &arg))
3063 return NULL;
3064 if (arg == Py_None) {
3065 /* optional time values not given */
3066 Py_BEGIN_ALLOW_THREADS
3067 res = utime(path, NULL);
3068 Py_END_ALLOW_THREADS
3069 }
3070 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3071 PyErr_SetString(PyExc_TypeError,
3072 "utime() arg 2 must be a tuple (atime, mtime)");
3073 PyMem_Free(path);
3074 return NULL;
3075 }
3076 else {
3077 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3078 &atime, &ausec) == -1) {
3079 PyMem_Free(path);
3080 return NULL;
3081 }
3082 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3083 &mtime, &musec) == -1) {
3084 PyMem_Free(path);
3085 return NULL;
3086 }
3087 ATIME = atime;
3088 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003089#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00003090 buf[0].tv_usec = ausec;
3091 buf[1].tv_usec = musec;
3092 Py_BEGIN_ALLOW_THREADS
3093 res = utimes(path, buf);
3094 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003095#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003096 Py_BEGIN_ALLOW_THREADS
3097 res = utime(path, UTIME_ARG);
3098 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003099#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003100 }
3101 if (res < 0) {
3102 return posix_error_with_allocated_filename(path);
3103 }
3104 PyMem_Free(path);
3105 Py_INCREF(Py_None);
3106 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003107#undef UTIME_ARG
3108#undef ATIME
3109#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003110#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003111}
3112
Guido van Rossum85e3b011991-06-03 12:42:10 +00003113
Guido van Rossum3b066191991-06-04 19:40:25 +00003114/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003115
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003116PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003117"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003118Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003119
Barry Warsaw53699e91996-12-10 23:23:01 +00003120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003121posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003122{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003123 int sts;
3124 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3125 return NULL;
3126 _exit(sts);
3127 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003128}
3129
Martin v. Löwis114619e2002-10-07 06:44:21 +00003130#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3131static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003132free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003133{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003134 Py_ssize_t i;
3135 for (i = 0; i < count; i++)
3136 PyMem_Free(array[i]);
3137 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138}
3139#endif
3140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003141
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003142#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003143PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003144"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003145Execute an executable path with arguments, replacing current process.\n\
3146\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003147 path: path of executable file\n\
3148 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003149
Barry Warsaw53699e91996-12-10 23:23:01 +00003150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003151posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003152{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003153 char *path;
3154 PyObject *argv;
3155 char **argvlist;
3156 Py_ssize_t i, argc;
3157 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003158
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 /* execv has two arguments: (path, argv), where
3160 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003161
Victor Stinnerd6f85422010-05-05 23:33:33 +00003162 if (!PyArg_ParseTuple(args, "etO:execv",
3163 Py_FileSystemDefaultEncoding,
3164 &path, &argv))
3165 return NULL;
3166 if (PyList_Check(argv)) {
3167 argc = PyList_Size(argv);
3168 getitem = PyList_GetItem;
3169 }
3170 else if (PyTuple_Check(argv)) {
3171 argc = PyTuple_Size(argv);
3172 getitem = PyTuple_GetItem;
3173 }
3174 else {
3175 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3176 PyMem_Free(path);
3177 return NULL;
3178 }
3179 if (argc < 1) {
3180 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3181 PyMem_Free(path);
3182 return NULL;
3183 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003184
Victor Stinnerd6f85422010-05-05 23:33:33 +00003185 argvlist = PyMem_NEW(char *, argc+1);
3186 if (argvlist == NULL) {
3187 PyMem_Free(path);
3188 return PyErr_NoMemory();
3189 }
3190 for (i = 0; i < argc; i++) {
3191 if (!PyArg_Parse((*getitem)(argv, i), "et",
3192 Py_FileSystemDefaultEncoding,
3193 &argvlist[i])) {
3194 free_string_array(argvlist, i);
3195 PyErr_SetString(PyExc_TypeError,
3196 "execv() arg 2 must contain only strings");
3197 PyMem_Free(path);
3198 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003199
Victor Stinnerd6f85422010-05-05 23:33:33 +00003200 }
3201 }
3202 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003203
Victor Stinnerd6f85422010-05-05 23:33:33 +00003204 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003205
Victor Stinnerd6f85422010-05-05 23:33:33 +00003206 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003207
Victor Stinnerd6f85422010-05-05 23:33:33 +00003208 free_string_array(argvlist, argc);
3209 PyMem_Free(path);
3210 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003211}
3212
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003214PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003215"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003216Execute a path with arguments and environment, replacing current process.\n\
3217\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003218 path: path of executable file\n\
3219 args: tuple or list of arguments\n\
3220 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221
Barry Warsaw53699e91996-12-10 23:23:01 +00003222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003223posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003224{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003225 char *path;
3226 PyObject *argv, *env;
3227 char **argvlist;
3228 char **envlist;
3229 PyObject *key, *val, *keys=NULL, *vals=NULL;
3230 Py_ssize_t i, pos, argc, envc;
3231 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3232 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003233
Victor Stinnerd6f85422010-05-05 23:33:33 +00003234 /* execve has three arguments: (path, argv, env), where
3235 argv is a list or tuple of strings and env is a dictionary
3236 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003237
Victor Stinnerd6f85422010-05-05 23:33:33 +00003238 if (!PyArg_ParseTuple(args, "etOO:execve",
3239 Py_FileSystemDefaultEncoding,
3240 &path, &argv, &env))
3241 return NULL;
3242 if (PyList_Check(argv)) {
3243 argc = PyList_Size(argv);
3244 getitem = PyList_GetItem;
3245 }
3246 else if (PyTuple_Check(argv)) {
3247 argc = PyTuple_Size(argv);
3248 getitem = PyTuple_GetItem;
3249 }
3250 else {
3251 PyErr_SetString(PyExc_TypeError,
3252 "execve() arg 2 must be a tuple or list");
3253 goto fail_0;
3254 }
3255 if (!PyMapping_Check(env)) {
3256 PyErr_SetString(PyExc_TypeError,
3257 "execve() arg 3 must be a mapping object");
3258 goto fail_0;
3259 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003260
Victor Stinnerd6f85422010-05-05 23:33:33 +00003261 argvlist = PyMem_NEW(char *, argc+1);
3262 if (argvlist == NULL) {
3263 PyErr_NoMemory();
3264 goto fail_0;
3265 }
3266 for (i = 0; i < argc; i++) {
3267 if (!PyArg_Parse((*getitem)(argv, i),
3268 "et;execve() arg 2 must contain only strings",
3269 Py_FileSystemDefaultEncoding,
3270 &argvlist[i]))
3271 {
3272 lastarg = i;
3273 goto fail_1;
3274 }
3275 }
3276 lastarg = argc;
3277 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003278
Victor Stinnerd6f85422010-05-05 23:33:33 +00003279 i = PyMapping_Size(env);
3280 if (i < 0)
3281 goto fail_1;
3282 envlist = PyMem_NEW(char *, i + 1);
3283 if (envlist == NULL) {
3284 PyErr_NoMemory();
3285 goto fail_1;
3286 }
3287 envc = 0;
3288 keys = PyMapping_Keys(env);
3289 vals = PyMapping_Values(env);
3290 if (!keys || !vals)
3291 goto fail_2;
3292 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3293 PyErr_SetString(PyExc_TypeError,
3294 "execve(): env.keys() or env.values() is not a list");
3295 goto fail_2;
3296 }
Tim Peters5aa91602002-01-30 05:46:57 +00003297
Victor Stinnerd6f85422010-05-05 23:33:33 +00003298 for (pos = 0; pos < i; pos++) {
3299 char *p, *k, *v;
3300 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003301
Victor Stinnerd6f85422010-05-05 23:33:33 +00003302 key = PyList_GetItem(keys, pos);
3303 val = PyList_GetItem(vals, pos);
3304 if (!key || !val)
3305 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003306
Victor Stinnerd6f85422010-05-05 23:33:33 +00003307 if (!PyArg_Parse(
3308 key,
3309 "s;execve() arg 3 contains a non-string key",
3310 &k) ||
3311 !PyArg_Parse(
3312 val,
3313 "s;execve() arg 3 contains a non-string value",
3314 &v))
3315 {
3316 goto fail_2;
3317 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003318
3319#if defined(PYOS_OS2)
3320 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3321 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3322#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003323 len = PyString_Size(key) + PyString_Size(val) + 2;
3324 p = PyMem_NEW(char, len);
3325 if (p == NULL) {
3326 PyErr_NoMemory();
3327 goto fail_2;
3328 }
3329 PyOS_snprintf(p, len, "%s=%s", k, v);
3330 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003331#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003332 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003333#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003334 }
3335 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003336
Victor Stinnerd6f85422010-05-05 23:33:33 +00003337 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003338
Victor Stinnerd6f85422010-05-05 23:33:33 +00003339 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003340
Victor Stinnerd6f85422010-05-05 23:33:33 +00003341 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003342
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003343 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003344 while (--envc >= 0)
3345 PyMem_DEL(envlist[envc]);
3346 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003347 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003348 free_string_array(argvlist, lastarg);
3349 Py_XDECREF(vals);
3350 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003351 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003352 PyMem_Free(path);
3353 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003354}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003355#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003357
Guido van Rossuma1065681999-01-25 23:20:23 +00003358#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003359PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003360"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003361Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003362\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003363 mode: mode of process creation\n\
3364 path: path of executable file\n\
3365 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003366
3367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003368posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003369{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003370 char *path;
3371 PyObject *argv;
3372 char **argvlist;
3373 int mode, i;
3374 Py_ssize_t argc;
3375 Py_intptr_t spawnval;
3376 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003377
Victor Stinnerd6f85422010-05-05 23:33:33 +00003378 /* spawnv has three arguments: (mode, path, argv), where
3379 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003380
Victor Stinnerd6f85422010-05-05 23:33:33 +00003381 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3382 Py_FileSystemDefaultEncoding,
3383 &path, &argv))
3384 return NULL;
3385 if (PyList_Check(argv)) {
3386 argc = PyList_Size(argv);
3387 getitem = PyList_GetItem;
3388 }
3389 else if (PyTuple_Check(argv)) {
3390 argc = PyTuple_Size(argv);
3391 getitem = PyTuple_GetItem;
3392 }
3393 else {
3394 PyErr_SetString(PyExc_TypeError,
3395 "spawnv() arg 2 must be a tuple or list");
3396 PyMem_Free(path);
3397 return NULL;
3398 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003399
Victor Stinnerd6f85422010-05-05 23:33:33 +00003400 argvlist = PyMem_NEW(char *, argc+1);
3401 if (argvlist == NULL) {
3402 PyMem_Free(path);
3403 return PyErr_NoMemory();
3404 }
3405 for (i = 0; i < argc; i++) {
3406 if (!PyArg_Parse((*getitem)(argv, i), "et",
3407 Py_FileSystemDefaultEncoding,
3408 &argvlist[i])) {
3409 free_string_array(argvlist, i);
3410 PyErr_SetString(
3411 PyExc_TypeError,
3412 "spawnv() arg 2 must contain only strings");
3413 PyMem_Free(path);
3414 return NULL;
3415 }
3416 }
3417 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003418
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003419#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003420 Py_BEGIN_ALLOW_THREADS
3421 spawnval = spawnv(mode, path, argvlist);
3422 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003423#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003424 if (mode == _OLD_P_OVERLAY)
3425 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003426
Victor Stinnerd6f85422010-05-05 23:33:33 +00003427 Py_BEGIN_ALLOW_THREADS
3428 spawnval = _spawnv(mode, path, argvlist);
3429 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003430#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003431
Victor Stinnerd6f85422010-05-05 23:33:33 +00003432 free_string_array(argvlist, argc);
3433 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003434
Victor Stinnerd6f85422010-05-05 23:33:33 +00003435 if (spawnval == -1)
3436 return posix_error();
3437 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003438#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003439 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003440#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003442#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003443}
3444
3445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003446PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003447"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003448Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003449\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003450 mode: mode of process creation\n\
3451 path: path of executable file\n\
3452 args: tuple or list of arguments\n\
3453 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003454
3455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003456posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003457{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003458 char *path;
3459 PyObject *argv, *env;
3460 char **argvlist;
3461 char **envlist;
3462 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3463 int mode, pos, envc;
3464 Py_ssize_t argc, i;
3465 Py_intptr_t spawnval;
3466 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3467 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003468
Victor Stinnerd6f85422010-05-05 23:33:33 +00003469 /* spawnve has four arguments: (mode, path, argv, env), where
3470 argv is a list or tuple of strings and env is a dictionary
3471 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003472
Victor Stinnerd6f85422010-05-05 23:33:33 +00003473 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3474 Py_FileSystemDefaultEncoding,
3475 &path, &argv, &env))
3476 return NULL;
3477 if (PyList_Check(argv)) {
3478 argc = PyList_Size(argv);
3479 getitem = PyList_GetItem;
3480 }
3481 else if (PyTuple_Check(argv)) {
3482 argc = PyTuple_Size(argv);
3483 getitem = PyTuple_GetItem;
3484 }
3485 else {
3486 PyErr_SetString(PyExc_TypeError,
3487 "spawnve() arg 2 must be a tuple or list");
3488 goto fail_0;
3489 }
3490 if (!PyMapping_Check(env)) {
3491 PyErr_SetString(PyExc_TypeError,
3492 "spawnve() arg 3 must be a mapping object");
3493 goto fail_0;
3494 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003495
Victor Stinnerd6f85422010-05-05 23:33:33 +00003496 argvlist = PyMem_NEW(char *, argc+1);
3497 if (argvlist == NULL) {
3498 PyErr_NoMemory();
3499 goto fail_0;
3500 }
3501 for (i = 0; i < argc; i++) {
3502 if (!PyArg_Parse((*getitem)(argv, i),
3503 "et;spawnve() arg 2 must contain only strings",
3504 Py_FileSystemDefaultEncoding,
3505 &argvlist[i]))
3506 {
3507 lastarg = i;
3508 goto fail_1;
3509 }
3510 }
3511 lastarg = argc;
3512 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003513
Victor Stinnerd6f85422010-05-05 23:33:33 +00003514 i = PyMapping_Size(env);
3515 if (i < 0)
3516 goto fail_1;
3517 envlist = PyMem_NEW(char *, i + 1);
3518 if (envlist == NULL) {
3519 PyErr_NoMemory();
3520 goto fail_1;
3521 }
3522 envc = 0;
3523 keys = PyMapping_Keys(env);
3524 vals = PyMapping_Values(env);
3525 if (!keys || !vals)
3526 goto fail_2;
3527 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3528 PyErr_SetString(PyExc_TypeError,
3529 "spawnve(): env.keys() or env.values() is not a list");
3530 goto fail_2;
3531 }
Tim Peters5aa91602002-01-30 05:46:57 +00003532
Victor Stinnerd6f85422010-05-05 23:33:33 +00003533 for (pos = 0; pos < i; pos++) {
3534 char *p, *k, *v;
3535 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003536
Victor Stinnerd6f85422010-05-05 23:33:33 +00003537 key = PyList_GetItem(keys, pos);
3538 val = PyList_GetItem(vals, pos);
3539 if (!key || !val)
3540 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003541
Victor Stinnerd6f85422010-05-05 23:33:33 +00003542 if (!PyArg_Parse(
3543 key,
3544 "s;spawnve() arg 3 contains a non-string key",
3545 &k) ||
3546 !PyArg_Parse(
3547 val,
3548 "s;spawnve() arg 3 contains a non-string value",
3549 &v))
3550 {
3551 goto fail_2;
3552 }
3553 len = PyString_Size(key) + PyString_Size(val) + 2;
3554 p = PyMem_NEW(char, len);
3555 if (p == NULL) {
3556 PyErr_NoMemory();
3557 goto fail_2;
3558 }
3559 PyOS_snprintf(p, len, "%s=%s", k, v);
3560 envlist[envc++] = p;
3561 }
3562 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003563
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003564#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003565 Py_BEGIN_ALLOW_THREADS
3566 spawnval = spawnve(mode, path, argvlist, envlist);
3567 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003568#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003569 if (mode == _OLD_P_OVERLAY)
3570 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003571
Victor Stinnerd6f85422010-05-05 23:33:33 +00003572 Py_BEGIN_ALLOW_THREADS
3573 spawnval = _spawnve(mode, path, argvlist, envlist);
3574 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003575#endif
Tim Peters25059d32001-12-07 20:35:43 +00003576
Victor Stinnerd6f85422010-05-05 23:33:33 +00003577 if (spawnval == -1)
3578 (void) posix_error();
3579 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003580#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003581 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003582#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003583 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003584#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003585
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003586 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003587 while (--envc >= 0)
3588 PyMem_DEL(envlist[envc]);
3589 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003590 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003591 free_string_array(argvlist, lastarg);
3592 Py_XDECREF(vals);
3593 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003594 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 PyMem_Free(path);
3596 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003597}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003598
3599/* OS/2 supports spawnvp & spawnvpe natively */
3600#if defined(PYOS_OS2)
3601PyDoc_STRVAR(posix_spawnvp__doc__,
3602"spawnvp(mode, file, args)\n\n\
3603Execute the program 'file' in a new process, using the environment\n\
3604search path to find the file.\n\
3605\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003606 mode: mode of process creation\n\
3607 file: executable file name\n\
3608 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003609
3610static PyObject *
3611posix_spawnvp(PyObject *self, PyObject *args)
3612{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003613 char *path;
3614 PyObject *argv;
3615 char **argvlist;
3616 int mode, i, argc;
3617 Py_intptr_t spawnval;
3618 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003619
Victor Stinnerd6f85422010-05-05 23:33:33 +00003620 /* spawnvp has three arguments: (mode, path, argv), where
3621 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3624 Py_FileSystemDefaultEncoding,
3625 &path, &argv))
3626 return NULL;
3627 if (PyList_Check(argv)) {
3628 argc = PyList_Size(argv);
3629 getitem = PyList_GetItem;
3630 }
3631 else if (PyTuple_Check(argv)) {
3632 argc = PyTuple_Size(argv);
3633 getitem = PyTuple_GetItem;
3634 }
3635 else {
3636 PyErr_SetString(PyExc_TypeError,
3637 "spawnvp() arg 2 must be a tuple or list");
3638 PyMem_Free(path);
3639 return NULL;
3640 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003641
Victor Stinnerd6f85422010-05-05 23:33:33 +00003642 argvlist = PyMem_NEW(char *, argc+1);
3643 if (argvlist == NULL) {
3644 PyMem_Free(path);
3645 return PyErr_NoMemory();
3646 }
3647 for (i = 0; i < argc; i++) {
3648 if (!PyArg_Parse((*getitem)(argv, i), "et",
3649 Py_FileSystemDefaultEncoding,
3650 &argvlist[i])) {
3651 free_string_array(argvlist, i);
3652 PyErr_SetString(
3653 PyExc_TypeError,
3654 "spawnvp() arg 2 must contain only strings");
3655 PyMem_Free(path);
3656 return NULL;
3657 }
3658 }
3659 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003660
Victor Stinnerd6f85422010-05-05 23:33:33 +00003661 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003662#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003663 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003664#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003665 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003666#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003667 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003668
Victor Stinnerd6f85422010-05-05 23:33:33 +00003669 free_string_array(argvlist, argc);
3670 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003671
Victor Stinnerd6f85422010-05-05 23:33:33 +00003672 if (spawnval == -1)
3673 return posix_error();
3674 else
3675 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003676}
3677
3678
3679PyDoc_STRVAR(posix_spawnvpe__doc__,
3680"spawnvpe(mode, file, args, env)\n\n\
3681Execute the program 'file' in a new process, using the environment\n\
3682search path to find the file.\n\
3683\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003684 mode: mode of process creation\n\
3685 file: executable file name\n\
3686 args: tuple or list of arguments\n\
3687 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003688
3689static PyObject *
3690posix_spawnvpe(PyObject *self, PyObject *args)
3691{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003692 char *path;
3693 PyObject *argv, *env;
3694 char **argvlist;
3695 char **envlist;
3696 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3697 int mode, i, pos, argc, envc;
3698 Py_intptr_t spawnval;
3699 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3700 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003701
Victor Stinnerd6f85422010-05-05 23:33:33 +00003702 /* spawnvpe has four arguments: (mode, path, argv, env), where
3703 argv is a list or tuple of strings and env is a dictionary
3704 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003705
Victor Stinnerd6f85422010-05-05 23:33:33 +00003706 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3707 Py_FileSystemDefaultEncoding,
3708 &path, &argv, &env))
3709 return NULL;
3710 if (PyList_Check(argv)) {
3711 argc = PyList_Size(argv);
3712 getitem = PyList_GetItem;
3713 }
3714 else if (PyTuple_Check(argv)) {
3715 argc = PyTuple_Size(argv);
3716 getitem = PyTuple_GetItem;
3717 }
3718 else {
3719 PyErr_SetString(PyExc_TypeError,
3720 "spawnvpe() arg 2 must be a tuple or list");
3721 goto fail_0;
3722 }
3723 if (!PyMapping_Check(env)) {
3724 PyErr_SetString(PyExc_TypeError,
3725 "spawnvpe() arg 3 must be a mapping object");
3726 goto fail_0;
3727 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003728
Victor Stinnerd6f85422010-05-05 23:33:33 +00003729 argvlist = PyMem_NEW(char *, argc+1);
3730 if (argvlist == NULL) {
3731 PyErr_NoMemory();
3732 goto fail_0;
3733 }
3734 for (i = 0; i < argc; i++) {
3735 if (!PyArg_Parse((*getitem)(argv, i),
3736 "et;spawnvpe() arg 2 must contain only strings",
3737 Py_FileSystemDefaultEncoding,
3738 &argvlist[i]))
3739 {
3740 lastarg = i;
3741 goto fail_1;
3742 }
3743 }
3744 lastarg = argc;
3745 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003746
Victor Stinnerd6f85422010-05-05 23:33:33 +00003747 i = PyMapping_Size(env);
3748 if (i < 0)
3749 goto fail_1;
3750 envlist = PyMem_NEW(char *, i + 1);
3751 if (envlist == NULL) {
3752 PyErr_NoMemory();
3753 goto fail_1;
3754 }
3755 envc = 0;
3756 keys = PyMapping_Keys(env);
3757 vals = PyMapping_Values(env);
3758 if (!keys || !vals)
3759 goto fail_2;
3760 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3761 PyErr_SetString(PyExc_TypeError,
3762 "spawnvpe(): env.keys() or env.values() is not a list");
3763 goto fail_2;
3764 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003765
Victor Stinnerd6f85422010-05-05 23:33:33 +00003766 for (pos = 0; pos < i; pos++) {
3767 char *p, *k, *v;
3768 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003769
Victor Stinnerd6f85422010-05-05 23:33:33 +00003770 key = PyList_GetItem(keys, pos);
3771 val = PyList_GetItem(vals, pos);
3772 if (!key || !val)
3773 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003774
Victor Stinnerd6f85422010-05-05 23:33:33 +00003775 if (!PyArg_Parse(
3776 key,
3777 "s;spawnvpe() arg 3 contains a non-string key",
3778 &k) ||
3779 !PyArg_Parse(
3780 val,
3781 "s;spawnvpe() arg 3 contains a non-string value",
3782 &v))
3783 {
3784 goto fail_2;
3785 }
3786 len = PyString_Size(key) + PyString_Size(val) + 2;
3787 p = PyMem_NEW(char, len);
3788 if (p == NULL) {
3789 PyErr_NoMemory();
3790 goto fail_2;
3791 }
3792 PyOS_snprintf(p, len, "%s=%s", k, v);
3793 envlist[envc++] = p;
3794 }
3795 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003796
Victor Stinnerd6f85422010-05-05 23:33:33 +00003797 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003798#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003799 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003800#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003801 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003802#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003803 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003804
Victor Stinnerd6f85422010-05-05 23:33:33 +00003805 if (spawnval == -1)
3806 (void) posix_error();
3807 else
3808 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003809
3810 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003811 while (--envc >= 0)
3812 PyMem_DEL(envlist[envc]);
3813 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003814 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003815 free_string_array(argvlist, lastarg);
3816 Py_XDECREF(vals);
3817 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003819 PyMem_Free(path);
3820 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003821}
3822#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003823#endif /* HAVE_SPAWNV */
3824
3825
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003826#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003827PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003828"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003829Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3830\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003831Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003832
3833static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003834posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003835{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003836 pid_t pid;
3837 int result = 0;
3838 _PyImport_AcquireLock();
3839 pid = fork1();
3840 if (pid == 0) {
3841 /* child: this clobbers and resets the import lock. */
3842 PyOS_AfterFork();
3843 } else {
3844 /* parent: release the import lock. */
3845 result = _PyImport_ReleaseLock();
3846 }
3847 if (pid == -1)
3848 return posix_error();
3849 if (result < 0) {
3850 /* Don't clobber the OSError if the fork failed. */
3851 PyErr_SetString(PyExc_RuntimeError,
3852 "not holding the import lock");
3853 return NULL;
3854 }
3855 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003856}
3857#endif
3858
3859
Guido van Rossumad0ee831995-03-01 10:34:45 +00003860#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003862"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003864Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003865
Barry Warsaw53699e91996-12-10 23:23:01 +00003866static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003867posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003868{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003869 pid_t pid;
3870 int result = 0;
3871 _PyImport_AcquireLock();
3872 pid = fork();
3873 if (pid == 0) {
3874 /* child: this clobbers and resets the import lock. */
3875 PyOS_AfterFork();
3876 } else {
3877 /* parent: release the import lock. */
3878 result = _PyImport_ReleaseLock();
3879 }
3880 if (pid == -1)
3881 return posix_error();
3882 if (result < 0) {
3883 /* Don't clobber the OSError if the fork failed. */
3884 PyErr_SetString(PyExc_RuntimeError,
3885 "not holding the import lock");
3886 return NULL;
3887 }
3888 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003889}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003890#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003891
Neal Norwitzb59798b2003-03-21 01:43:31 +00003892/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003893/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3894#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003895#define DEV_PTY_FILE "/dev/ptc"
3896#define HAVE_DEV_PTMX
3897#else
3898#define DEV_PTY_FILE "/dev/ptmx"
3899#endif
3900
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003901#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003902#ifdef HAVE_PTY_H
3903#include <pty.h>
3904#else
3905#ifdef HAVE_LIBUTIL_H
3906#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003907#else
3908#ifdef HAVE_UTIL_H
3909#include <util.h>
3910#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003911#endif /* HAVE_LIBUTIL_H */
3912#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003913#ifdef HAVE_STROPTS_H
3914#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003915#endif
3916#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003917
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003918#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003919PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003920"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003921Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003922
3923static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003924posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003925{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003926 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003927#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003928 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003929#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003930#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003931 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003932#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003933 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003934#endif
3935#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003936
Thomas Wouters70c21a12000-07-14 14:28:33 +00003937#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003938 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3939 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003940#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003941 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3942 if (slave_name == NULL)
3943 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003944
Victor Stinnerd6f85422010-05-05 23:33:33 +00003945 slave_fd = open(slave_name, O_RDWR);
3946 if (slave_fd < 0)
3947 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003948#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003949 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3950 if (master_fd < 0)
3951 return posix_error();
3952 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3953 /* change permission of slave */
3954 if (grantpt(master_fd) < 0) {
3955 PyOS_setsig(SIGCHLD, sig_saved);
3956 return posix_error();
3957 }
3958 /* unlock slave */
3959 if (unlockpt(master_fd) < 0) {
3960 PyOS_setsig(SIGCHLD, sig_saved);
3961 return posix_error();
3962 }
3963 PyOS_setsig(SIGCHLD, sig_saved);
3964 slave_name = ptsname(master_fd); /* get name of slave */
3965 if (slave_name == NULL)
3966 return posix_error();
3967 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3968 if (slave_fd < 0)
3969 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003970#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003971 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3972 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003973#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003974 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003975#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003976#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003977#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003978
Victor Stinnerd6f85422010-05-05 23:33:33 +00003979 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003980
Fred Drake8cef4cf2000-06-28 16:40:38 +00003981}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003982#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003983
3984#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003985PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003986"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003987Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3988Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003989To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003990
3991static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003992posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003993{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003994 int master_fd = -1, result = 0;
3995 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003996
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 _PyImport_AcquireLock();
3998 pid = forkpty(&master_fd, NULL, NULL, NULL);
3999 if (pid == 0) {
4000 /* child: this clobbers and resets the import lock. */
4001 PyOS_AfterFork();
4002 } else {
4003 /* parent: release the import lock. */
4004 result = _PyImport_ReleaseLock();
4005 }
4006 if (pid == -1)
4007 return posix_error();
4008 if (result < 0) {
4009 /* Don't clobber the OSError if the fork failed. */
4010 PyErr_SetString(PyExc_RuntimeError,
4011 "not holding the import lock");
4012 return NULL;
4013 }
4014 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004015}
4016#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004017
Guido van Rossumad0ee831995-03-01 10:34:45 +00004018#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004019PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004020"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004021Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004022
Barry Warsaw53699e91996-12-10 23:23:01 +00004023static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004024posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004025{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004026 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004027}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004028#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004030
Guido van Rossumad0ee831995-03-01 10:34:45 +00004031#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004032PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004033"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004035
Barry Warsaw53699e91996-12-10 23:23:01 +00004036static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004037posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004038{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004039 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004040}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004041#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004043
Guido van Rossumad0ee831995-03-01 10:34:45 +00004044#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004046"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004047Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Barry Warsaw53699e91996-12-10 23:23:01 +00004049static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004050posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004051{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004052 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004053}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004054#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004055
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004056
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004060
Barry Warsaw53699e91996-12-10 23:23:01 +00004061static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004062posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004063{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004064 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004065}
4066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004067
Fred Drakec9680921999-12-13 16:37:25 +00004068#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004070"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004071Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004072
4073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004074posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004075{
4076 PyObject *result = NULL;
4077
Fred Drakec9680921999-12-13 16:37:25 +00004078#ifdef NGROUPS_MAX
4079#define MAX_GROUPS NGROUPS_MAX
4080#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004081 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004082#define MAX_GROUPS 64
4083#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004084 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004085
Victor Stinner59729ff2011-07-05 11:28:19 +02004086 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004087 * This is a helper variable to store the intermediate result when
4088 * that happens.
4089 *
4090 * To keep the code readable the OSX behaviour is unconditional,
4091 * according to the POSIX spec this should be safe on all unix-y
4092 * systems.
4093 */
4094 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004095 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004096
Ned Deily80743642013-08-01 21:19:09 -07004097#ifdef __APPLE__
4098 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4099 * there are more groups than can fit in grouplist. Therefore, on OS X
4100 * always first call getgroups with length 0 to get the actual number
4101 * of groups.
4102 */
4103 n = getgroups(0, NULL);
4104 if (n < 0) {
4105 return posix_error();
4106 } else if (n <= MAX_GROUPS) {
4107 /* groups will fit in existing array */
4108 alt_grouplist = grouplist;
4109 } else {
4110 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4111 if (alt_grouplist == NULL) {
4112 errno = EINVAL;
4113 return posix_error();
4114 }
4115 }
4116
4117 n = getgroups(n, alt_grouplist);
4118 if (n == -1) {
4119 if (alt_grouplist != grouplist) {
4120 PyMem_Free(alt_grouplist);
4121 }
4122 return posix_error();
4123 }
4124#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004125 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004126 if (n < 0) {
4127 if (errno == EINVAL) {
4128 n = getgroups(0, NULL);
4129 if (n == -1) {
4130 return posix_error();
4131 }
4132 if (n == 0) {
4133 /* Avoid malloc(0) */
4134 alt_grouplist = grouplist;
4135 } else {
4136 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4137 if (alt_grouplist == NULL) {
4138 errno = EINVAL;
4139 return posix_error();
4140 }
4141 n = getgroups(n, alt_grouplist);
4142 if (n == -1) {
4143 PyMem_Free(alt_grouplist);
4144 return posix_error();
4145 }
4146 }
4147 } else {
4148 return posix_error();
4149 }
4150 }
Ned Deily80743642013-08-01 21:19:09 -07004151#endif
4152
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004153 result = PyList_New(n);
4154 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004155 int i;
4156 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004157 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004158 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004159 Py_DECREF(result);
4160 result = NULL;
4161 break;
Fred Drakec9680921999-12-13 16:37:25 +00004162 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004163 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004164 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004165 }
4166
4167 if (alt_grouplist != grouplist) {
4168 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004170
Fred Drakec9680921999-12-13 16:37:25 +00004171 return result;
4172}
4173#endif
4174
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004175#ifdef HAVE_INITGROUPS
4176PyDoc_STRVAR(posix_initgroups__doc__,
4177"initgroups(username, gid) -> None\n\n\
4178Call the system initgroups() to initialize the group access list with all of\n\
4179the groups of which the specified username is a member, plus the specified\n\
4180group id.");
4181
4182static PyObject *
4183posix_initgroups(PyObject *self, PyObject *args)
4184{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004185 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004186#ifdef __APPLE__
4187 int gid;
4188#else
4189 gid_t gid;
4190#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004191
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004192#ifdef __APPLE__
4193 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4194 &gid))
4195#else
4196 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4197 _Py_Gid_Converter, &gid))
4198#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004199 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004200
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004201 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004202 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004203
Victor Stinnerd6f85422010-05-05 23:33:33 +00004204 Py_INCREF(Py_None);
4205 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004206}
4207#endif
4208
Martin v. Löwis606edc12002-06-13 21:09:11 +00004209#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004210PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004211"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004212Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004213
4214static PyObject *
4215posix_getpgid(PyObject *self, PyObject *args)
4216{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004217 pid_t pid, pgid;
4218 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4219 return NULL;
4220 pgid = getpgid(pid);
4221 if (pgid < 0)
4222 return posix_error();
4223 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004224}
4225#endif /* HAVE_GETPGID */
4226
4227
Guido van Rossumb6775db1994-08-01 11:34:53 +00004228#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004230"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004231Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004232
Barry Warsaw53699e91996-12-10 23:23:01 +00004233static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004234posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004235{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004236#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004237 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004238#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004239 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004240#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004241}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004242#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004243
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004244
Guido van Rossumb6775db1994-08-01 11:34:53 +00004245#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004246PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004247"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004248Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004249
Barry Warsaw53699e91996-12-10 23:23:01 +00004250static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004251posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004252{
Guido van Rossum64933891994-10-20 21:56:42 +00004253#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004254 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004255#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004256 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004257#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004258 return posix_error();
4259 Py_INCREF(Py_None);
4260 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004261}
4262
Guido van Rossumb6775db1994-08-01 11:34:53 +00004263#endif /* HAVE_SETPGRP */
4264
Guido van Rossumad0ee831995-03-01 10:34:45 +00004265#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004267"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004268Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Barry Warsaw53699e91996-12-10 23:23:01 +00004270static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004271posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004272{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004273 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004274}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004275#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004277
Fred Drake12c6e2d1999-12-14 21:25:03 +00004278#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004279PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004280"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004281Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004282
4283static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004284posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004285{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004286 PyObject *result = NULL;
4287 char *name;
4288 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004289
Victor Stinnerd6f85422010-05-05 23:33:33 +00004290 errno = 0;
4291 name = getlogin();
4292 if (name == NULL) {
4293 if (errno)
4294 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004295 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004296 PyErr_SetString(PyExc_OSError,
4297 "unable to determine login name");
4298 }
4299 else
4300 result = PyString_FromString(name);
4301 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004302
Fred Drake12c6e2d1999-12-14 21:25:03 +00004303 return result;
4304}
4305#endif
4306
Guido van Rossumad0ee831995-03-01 10:34:45 +00004307#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004308PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004309"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004310Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004311
Barry Warsaw53699e91996-12-10 23:23:01 +00004312static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004313posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004314{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004315 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004316}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004317#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004319
Guido van Rossumad0ee831995-03-01 10:34:45 +00004320#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004321PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004322"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004324
Barry Warsaw53699e91996-12-10 23:23:01 +00004325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004326posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004327{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004328 pid_t pid;
4329 int sig;
4330 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4331 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004332#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004333 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4334 APIRET rc;
4335 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004336 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004337
4338 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4339 APIRET rc;
4340 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004341 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004342
4343 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004344 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004345#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004346 if (kill(pid, sig) == -1)
4347 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004348#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004349 Py_INCREF(Py_None);
4350 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004351}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004352#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004353
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004354#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004355PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004356"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004358
4359static PyObject *
4360posix_killpg(PyObject *self, PyObject *args)
4361{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004362 int sig;
4363 pid_t pgid;
4364 /* XXX some man pages make the `pgid` parameter an int, others
4365 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4366 take the same type. Moreover, pid_t is always at least as wide as
4367 int (else compilation of this module fails), which is safe. */
4368 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4369 return NULL;
4370 if (killpg(pgid, sig) == -1)
4371 return posix_error();
4372 Py_INCREF(Py_None);
4373 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004374}
4375#endif
4376
Brian Curtine5aa8862010-04-02 23:26:06 +00004377#ifdef MS_WINDOWS
4378PyDoc_STRVAR(win32_kill__doc__,
4379"kill(pid, sig)\n\n\
4380Kill a process with a signal.");
4381
4382static PyObject *
4383win32_kill(PyObject *self, PyObject *args)
4384{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004385 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004386 DWORD pid, sig, err;
4387 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004388
Victor Stinnerd6f85422010-05-05 23:33:33 +00004389 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4390 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004391
Victor Stinnerd6f85422010-05-05 23:33:33 +00004392 /* Console processes which share a common console can be sent CTRL+C or
4393 CTRL+BREAK events, provided they handle said events. */
4394 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4395 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4396 err = GetLastError();
4397 return PyErr_SetFromWindowsErr(err);
4398 }
4399 else
4400 Py_RETURN_NONE;
4401 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004402
Victor Stinnerd6f85422010-05-05 23:33:33 +00004403 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4404 attempt to open and terminate the process. */
4405 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4406 if (handle == NULL) {
4407 err = GetLastError();
4408 return PyErr_SetFromWindowsErr(err);
4409 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004410
Victor Stinnerd6f85422010-05-05 23:33:33 +00004411 if (TerminateProcess(handle, sig) == 0) {
4412 err = GetLastError();
4413 result = PyErr_SetFromWindowsErr(err);
4414 } else {
4415 Py_INCREF(Py_None);
4416 result = Py_None;
4417 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004418
Victor Stinnerd6f85422010-05-05 23:33:33 +00004419 CloseHandle(handle);
4420 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004421}
Brian Curtincaea7e82011-06-08 19:29:53 -05004422
Brian Curtin5446f082011-06-09 10:00:42 -05004423PyDoc_STRVAR(posix__isdir__doc__,
4424"Return true if the pathname refers to an existing directory.");
4425
Brian Curtincaea7e82011-06-08 19:29:53 -05004426static PyObject *
4427posix__isdir(PyObject *self, PyObject *args)
4428{
Brian Curtincaea7e82011-06-08 19:29:53 -05004429 char *path;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004430 Py_UNICODE *wpath;
Brian Curtincaea7e82011-06-08 19:29:53 -05004431 DWORD attributes;
4432
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004433 if (PyArg_ParseTuple(args, "u|:_isdir", &wpath)) {
Brian Curtincaea7e82011-06-08 19:29:53 -05004434 attributes = GetFileAttributesW(wpath);
4435 if (attributes == INVALID_FILE_ATTRIBUTES)
4436 Py_RETURN_FALSE;
4437 goto check;
4438 }
4439 /* Drop the argument parsing error as narrow strings
4440 are also valid. */
4441 PyErr_Clear();
4442
4443 if (!PyArg_ParseTuple(args, "et:_isdir",
4444 Py_FileSystemDefaultEncoding, &path))
4445 return NULL;
4446
4447 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004448 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004449 if (attributes == INVALID_FILE_ATTRIBUTES)
4450 Py_RETURN_FALSE;
4451
4452check:
4453 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4454 Py_RETURN_TRUE;
4455 else
4456 Py_RETURN_FALSE;
4457}
Brian Curtine5aa8862010-04-02 23:26:06 +00004458#endif /* MS_WINDOWS */
4459
Guido van Rossumc0125471996-06-28 18:55:32 +00004460#ifdef HAVE_PLOCK
4461
4462#ifdef HAVE_SYS_LOCK_H
4463#include <sys/lock.h>
4464#endif
4465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004466PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004467"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004468Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004469
Barry Warsaw53699e91996-12-10 23:23:01 +00004470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004471posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004472{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004473 int op;
4474 if (!PyArg_ParseTuple(args, "i:plock", &op))
4475 return NULL;
4476 if (plock(op) == -1)
4477 return posix_error();
4478 Py_INCREF(Py_None);
4479 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004480}
4481#endif
4482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004483
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004484#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004485PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004486"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004487Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004488
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004489#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004490#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004491static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004492async_system(const char *command)
4493{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004494 char errormsg[256], args[1024];
4495 RESULTCODES rcodes;
4496 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004497
Victor Stinnerd6f85422010-05-05 23:33:33 +00004498 char *shell = getenv("COMSPEC");
4499 if (!shell)
4500 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004501
Victor Stinnerd6f85422010-05-05 23:33:33 +00004502 /* avoid overflowing the argument buffer */
4503 if (strlen(shell) + 3 + strlen(command) >= 1024)
4504 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004505
Victor Stinnerd6f85422010-05-05 23:33:33 +00004506 args[0] = '\0';
4507 strcat(args, shell);
4508 strcat(args, "/c ");
4509 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004510
Victor Stinnerd6f85422010-05-05 23:33:33 +00004511 /* execute asynchronously, inheriting the environment */
4512 rc = DosExecPgm(errormsg,
4513 sizeof(errormsg),
4514 EXEC_ASYNC,
4515 args,
4516 NULL,
4517 &rcodes,
4518 shell);
4519 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004520}
4521
Guido van Rossumd48f2521997-12-05 22:19:34 +00004522static FILE *
4523popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004524{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004525 int oldfd, tgtfd;
4526 HFILE pipeh[2];
4527 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004528
Victor Stinnerd6f85422010-05-05 23:33:33 +00004529 /* mode determines which of stdin or stdout is reconnected to
4530 * the pipe to the child
4531 */
4532 if (strchr(mode, 'r') != NULL) {
4533 tgt_fd = 1; /* stdout */
4534 } else if (strchr(mode, 'w')) {
4535 tgt_fd = 0; /* stdin */
4536 } else {
4537 *err = ERROR_INVALID_ACCESS;
4538 return NULL;
4539 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004540
Victor Stinnerd6f85422010-05-05 23:33:33 +00004541 /* setup the pipe */
4542 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4543 *err = rc;
4544 return NULL;
4545 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004546
Victor Stinnerd6f85422010-05-05 23:33:33 +00004547 /* prevent other threads accessing stdio */
4548 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004549
Victor Stinnerd6f85422010-05-05 23:33:33 +00004550 /* reconnect stdio and execute child */
4551 oldfd = dup(tgtfd);
4552 close(tgtfd);
4553 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4554 DosClose(pipeh[tgtfd]);
4555 rc = async_system(command);
4556 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004557
Victor Stinnerd6f85422010-05-05 23:33:33 +00004558 /* restore stdio */
4559 dup2(oldfd, tgtfd);
4560 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004561
Victor Stinnerd6f85422010-05-05 23:33:33 +00004562 /* allow other threads access to stdio */
4563 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004564
Victor Stinnerd6f85422010-05-05 23:33:33 +00004565 /* if execution of child was successful return file stream */
4566 if (rc == NO_ERROR)
4567 return fdopen(pipeh[1 - tgtfd], mode);
4568 else {
4569 DosClose(pipeh[1 - tgtfd]);
4570 *err = rc;
4571 return NULL;
4572 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004573}
4574
4575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004576posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004577{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004578 char *name;
4579 char *mode = "r";
4580 int err, bufsize = -1;
4581 FILE *fp;
4582 PyObject *f;
4583 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4584 return NULL;
4585 Py_BEGIN_ALLOW_THREADS
4586 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4587 Py_END_ALLOW_THREADS
4588 if (fp == NULL)
4589 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004590
Victor Stinnerd6f85422010-05-05 23:33:33 +00004591 f = PyFile_FromFile(fp, name, mode, fclose);
4592 if (f != NULL)
4593 PyFile_SetBufSize(f, bufsize);
4594 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004595}
4596
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004597#elif defined(PYCC_GCC)
4598
4599/* standard posix version of popen() support */
4600static PyObject *
4601posix_popen(PyObject *self, PyObject *args)
4602{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004603 char *name;
4604 char *mode = "r";
4605 int bufsize = -1;
4606 FILE *fp;
4607 PyObject *f;
4608 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4609 return NULL;
4610 Py_BEGIN_ALLOW_THREADS
4611 fp = popen(name, mode);
4612 Py_END_ALLOW_THREADS
4613 if (fp == NULL)
4614 return posix_error();
4615 f = PyFile_FromFile(fp, name, mode, pclose);
4616 if (f != NULL)
4617 PyFile_SetBufSize(f, bufsize);
4618 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004619}
4620
4621/* fork() under OS/2 has lots'o'warts
4622 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4623 * most of this code is a ripoff of the win32 code, but using the
4624 * capabilities of EMX's C library routines
4625 */
4626
4627/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4628#define POPEN_1 1
4629#define POPEN_2 2
4630#define POPEN_3 3
4631#define POPEN_4 4
4632
4633static PyObject *_PyPopen(char *, int, int, int);
4634static int _PyPclose(FILE *file);
4635
4636/*
4637 * Internal dictionary mapping popen* file pointers to process handles,
4638 * for use when retrieving the process exit code. See _PyPclose() below
4639 * for more information on this dictionary's use.
4640 */
4641static PyObject *_PyPopenProcs = NULL;
4642
4643/* os2emx version of popen2()
4644 *
4645 * The result of this function is a pipe (file) connected to the
4646 * process's stdin, and a pipe connected to the process's stdout.
4647 */
4648
4649static PyObject *
4650os2emx_popen2(PyObject *self, PyObject *args)
4651{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004652 PyObject *f;
4653 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004654
Victor Stinnerd6f85422010-05-05 23:33:33 +00004655 char *cmdstring;
4656 char *mode = "t";
4657 int bufsize = -1;
4658 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4659 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004660
Victor Stinnerd6f85422010-05-05 23:33:33 +00004661 if (*mode == 't')
4662 tm = O_TEXT;
4663 else if (*mode != 'b') {
4664 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4665 return NULL;
4666 } else
4667 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004668
Victor Stinnerd6f85422010-05-05 23:33:33 +00004669 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004670
Victor Stinnerd6f85422010-05-05 23:33:33 +00004671 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004672}
4673
4674/*
4675 * Variation on os2emx.popen2
4676 *
4677 * The result of this function is 3 pipes - the process's stdin,
4678 * stdout and stderr
4679 */
4680
4681static PyObject *
4682os2emx_popen3(PyObject *self, PyObject *args)
4683{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004684 PyObject *f;
4685 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004686
Victor Stinnerd6f85422010-05-05 23:33:33 +00004687 char *cmdstring;
4688 char *mode = "t";
4689 int bufsize = -1;
4690 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4691 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004692
Victor Stinnerd6f85422010-05-05 23:33:33 +00004693 if (*mode == 't')
4694 tm = O_TEXT;
4695 else if (*mode != 'b') {
4696 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4697 return NULL;
4698 } else
4699 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004700
Victor Stinnerd6f85422010-05-05 23:33:33 +00004701 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004702
Victor Stinnerd6f85422010-05-05 23:33:33 +00004703 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004704}
4705
4706/*
4707 * Variation on os2emx.popen2
4708 *
Tim Peters11b23062003-04-23 02:39:17 +00004709 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004710 * and stdout+stderr combined as a single pipe.
4711 */
4712
4713static PyObject *
4714os2emx_popen4(PyObject *self, PyObject *args)
4715{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004716 PyObject *f;
4717 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004718
Victor Stinnerd6f85422010-05-05 23:33:33 +00004719 char *cmdstring;
4720 char *mode = "t";
4721 int bufsize = -1;
4722 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4723 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004724
Victor Stinnerd6f85422010-05-05 23:33:33 +00004725 if (*mode == 't')
4726 tm = O_TEXT;
4727 else if (*mode != 'b') {
4728 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4729 return NULL;
4730 } else
4731 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004732
Victor Stinnerd6f85422010-05-05 23:33:33 +00004733 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004734
Victor Stinnerd6f85422010-05-05 23:33:33 +00004735 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004736}
4737
4738/* a couple of structures for convenient handling of multiple
4739 * file handles and pipes
4740 */
4741struct file_ref
4742{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004743 int handle;
4744 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004745};
4746
4747struct pipe_ref
4748{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004749 int rd;
4750 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004751};
4752
4753/* The following code is derived from the win32 code */
4754
4755static PyObject *
4756_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4757{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004758 struct file_ref stdio[3];
4759 struct pipe_ref p_fd[3];
4760 FILE *p_s[3];
4761 int file_count, i, pipe_err;
4762 pid_t pipe_pid;
4763 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4764 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004765
Victor Stinnerd6f85422010-05-05 23:33:33 +00004766 /* file modes for subsequent fdopen's on pipe handles */
4767 if (mode == O_TEXT)
4768 {
4769 rd_mode = "rt";
4770 wr_mode = "wt";
4771 }
4772 else
4773 {
4774 rd_mode = "rb";
4775 wr_mode = "wb";
4776 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004777
Victor Stinnerd6f85422010-05-05 23:33:33 +00004778 /* prepare shell references */
4779 if ((shell = getenv("EMXSHELL")) == NULL)
4780 if ((shell = getenv("COMSPEC")) == NULL)
4781 {
4782 errno = ENOENT;
4783 return posix_error();
4784 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004785
Victor Stinnerd6f85422010-05-05 23:33:33 +00004786 sh_name = _getname(shell);
4787 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4788 opt = "/c";
4789 else
4790 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004791
Victor Stinnerd6f85422010-05-05 23:33:33 +00004792 /* save current stdio fds + their flags, and set not inheritable */
4793 i = pipe_err = 0;
4794 while (pipe_err >= 0 && i < 3)
4795 {
4796 pipe_err = stdio[i].handle = dup(i);
4797 stdio[i].flags = fcntl(i, F_GETFD, 0);
4798 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4799 i++;
4800 }
4801 if (pipe_err < 0)
4802 {
4803 /* didn't get them all saved - clean up and bail out */
4804 int saved_err = errno;
4805 while (i-- > 0)
4806 {
4807 close(stdio[i].handle);
4808 }
4809 errno = saved_err;
4810 return posix_error();
4811 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004812
Victor Stinnerd6f85422010-05-05 23:33:33 +00004813 /* create pipe ends */
4814 file_count = 2;
4815 if (n == POPEN_3)
4816 file_count = 3;
4817 i = pipe_err = 0;
4818 while ((pipe_err == 0) && (i < file_count))
4819 pipe_err = pipe((int *)&p_fd[i++]);
4820 if (pipe_err < 0)
4821 {
4822 /* didn't get them all made - clean up and bail out */
4823 while (i-- > 0)
4824 {
4825 close(p_fd[i].wr);
4826 close(p_fd[i].rd);
4827 }
4828 errno = EPIPE;
4829 return posix_error();
4830 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004831
Victor Stinnerd6f85422010-05-05 23:33:33 +00004832 /* change the actual standard IO streams over temporarily,
4833 * making the retained pipe ends non-inheritable
4834 */
4835 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004836
Victor Stinnerd6f85422010-05-05 23:33:33 +00004837 /* - stdin */
4838 if (dup2(p_fd[0].rd, 0) == 0)
4839 {
4840 close(p_fd[0].rd);
4841 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4842 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4843 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4844 {
4845 close(p_fd[0].wr);
4846 pipe_err = -1;
4847 }
4848 }
4849 else
4850 {
4851 pipe_err = -1;
4852 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004853
Victor Stinnerd6f85422010-05-05 23:33:33 +00004854 /* - stdout */
4855 if (pipe_err == 0)
4856 {
4857 if (dup2(p_fd[1].wr, 1) == 1)
4858 {
4859 close(p_fd[1].wr);
4860 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4861 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4862 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4863 {
4864 close(p_fd[1].rd);
4865 pipe_err = -1;
4866 }
4867 }
4868 else
4869 {
4870 pipe_err = -1;
4871 }
4872 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004873
Victor Stinnerd6f85422010-05-05 23:33:33 +00004874 /* - stderr, as required */
4875 if (pipe_err == 0)
4876 switch (n)
4877 {
4878 case POPEN_3:
4879 {
4880 if (dup2(p_fd[2].wr, 2) == 2)
4881 {
4882 close(p_fd[2].wr);
4883 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4884 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4885 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4886 {
4887 close(p_fd[2].rd);
4888 pipe_err = -1;
4889 }
4890 }
4891 else
4892 {
4893 pipe_err = -1;
4894 }
4895 break;
4896 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004897
Victor Stinnerd6f85422010-05-05 23:33:33 +00004898 case POPEN_4:
4899 {
4900 if (dup2(1, 2) != 2)
4901 {
4902 pipe_err = -1;
4903 }
4904 break;
4905 }
4906 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004907
Victor Stinnerd6f85422010-05-05 23:33:33 +00004908 /* spawn the child process */
4909 if (pipe_err == 0)
4910 {
4911 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4912 if (pipe_pid == -1)
4913 {
4914 pipe_err = -1;
4915 }
4916 else
4917 {
4918 /* save the PID into the FILE structure
4919 * NOTE: this implementation doesn't actually
4920 * take advantage of this, but do it for
4921 * completeness - AIM Apr01
4922 */
4923 for (i = 0; i < file_count; i++)
4924 p_s[i]->_pid = pipe_pid;
4925 }
4926 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004927
Victor Stinnerd6f85422010-05-05 23:33:33 +00004928 /* reset standard IO to normal */
4929 for (i = 0; i < 3; i++)
4930 {
4931 dup2(stdio[i].handle, i);
4932 fcntl(i, F_SETFD, stdio[i].flags);
4933 close(stdio[i].handle);
4934 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004935
Victor Stinnerd6f85422010-05-05 23:33:33 +00004936 /* if any remnant problems, clean up and bail out */
4937 if (pipe_err < 0)
4938 {
4939 for (i = 0; i < 3; i++)
4940 {
4941 close(p_fd[i].rd);
4942 close(p_fd[i].wr);
4943 }
4944 errno = EPIPE;
4945 return posix_error_with_filename(cmdstring);
4946 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004947
Victor Stinnerd6f85422010-05-05 23:33:33 +00004948 /* build tuple of file objects to return */
4949 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4950 PyFile_SetBufSize(p_f[0], bufsize);
4951 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4952 PyFile_SetBufSize(p_f[1], bufsize);
4953 if (n == POPEN_3)
4954 {
4955 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4956 PyFile_SetBufSize(p_f[0], bufsize);
4957 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4958 }
4959 else
4960 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004961
Victor Stinnerd6f85422010-05-05 23:33:33 +00004962 /*
4963 * Insert the files we've created into the process dictionary
4964 * all referencing the list with the process handle and the
4965 * initial number of files (see description below in _PyPclose).
4966 * Since if _PyPclose later tried to wait on a process when all
4967 * handles weren't closed, it could create a deadlock with the
4968 * child, we spend some energy here to try to ensure that we
4969 * either insert all file handles into the dictionary or none
4970 * at all. It's a little clumsy with the various popen modes
4971 * and variable number of files involved.
4972 */
4973 if (!_PyPopenProcs)
4974 {
4975 _PyPopenProcs = PyDict_New();
4976 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004977
Victor Stinnerd6f85422010-05-05 23:33:33 +00004978 if (_PyPopenProcs)
4979 {
4980 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4981 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004982
Victor Stinnerd6f85422010-05-05 23:33:33 +00004983 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4984 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004985
Victor Stinnerd6f85422010-05-05 23:33:33 +00004986 procObj = PyList_New(2);
4987 pidObj = PyLong_FromPid(pipe_pid);
4988 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004989
Victor Stinnerd6f85422010-05-05 23:33:33 +00004990 if (procObj && pidObj && intObj)
4991 {
4992 PyList_SetItem(procObj, 0, pidObj);
4993 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004994
Victor Stinnerd6f85422010-05-05 23:33:33 +00004995 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4996 if (fileObj[0])
4997 {
4998 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4999 fileObj[0],
5000 procObj);
5001 }
5002 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5003 if (fileObj[1])
5004 {
5005 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5006 fileObj[1],
5007 procObj);
5008 }
5009 if (file_count >= 3)
5010 {
5011 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5012 if (fileObj[2])
5013 {
5014 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5015 fileObj[2],
5016 procObj);
5017 }
5018 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005019
Victor Stinnerd6f85422010-05-05 23:33:33 +00005020 if (ins_rc[0] < 0 || !fileObj[0] ||
5021 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5022 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5023 {
5024 /* Something failed - remove any dictionary
5025 * entries that did make it.
5026 */
5027 if (!ins_rc[0] && fileObj[0])
5028 {
5029 PyDict_DelItem(_PyPopenProcs,
5030 fileObj[0]);
5031 }
5032 if (!ins_rc[1] && fileObj[1])
5033 {
5034 PyDict_DelItem(_PyPopenProcs,
5035 fileObj[1]);
5036 }
5037 if (!ins_rc[2] && fileObj[2])
5038 {
5039 PyDict_DelItem(_PyPopenProcs,
5040 fileObj[2]);
5041 }
5042 }
5043 }
Tim Peters11b23062003-04-23 02:39:17 +00005044
Victor Stinnerd6f85422010-05-05 23:33:33 +00005045 /*
5046 * Clean up our localized references for the dictionary keys
5047 * and value since PyDict_SetItem will Py_INCREF any copies
5048 * that got placed in the dictionary.
5049 */
5050 Py_XDECREF(procObj);
5051 Py_XDECREF(fileObj[0]);
5052 Py_XDECREF(fileObj[1]);
5053 Py_XDECREF(fileObj[2]);
5054 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005055
Victor Stinnerd6f85422010-05-05 23:33:33 +00005056 /* Child is launched. */
5057 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005058}
5059
5060/*
5061 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5062 * exit code for the child process and return as a result of the close.
5063 *
5064 * This function uses the _PyPopenProcs dictionary in order to map the
5065 * input file pointer to information about the process that was
5066 * originally created by the popen* call that created the file pointer.
5067 * The dictionary uses the file pointer as a key (with one entry
5068 * inserted for each file returned by the original popen* call) and a
5069 * single list object as the value for all files from a single call.
5070 * The list object contains the Win32 process handle at [0], and a file
5071 * count at [1], which is initialized to the total number of file
5072 * handles using that list.
5073 *
5074 * This function closes whichever handle it is passed, and decrements
5075 * the file count in the dictionary for the process handle pointed to
5076 * by this file. On the last close (when the file count reaches zero),
5077 * this function will wait for the child process and then return its
5078 * exit code as the result of the close() operation. This permits the
5079 * files to be closed in any order - it is always the close() of the
5080 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005081 *
5082 * NOTE: This function is currently called with the GIL released.
5083 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005084 */
5085
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005086static int _PyPclose(FILE *file)
5087{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005088 int result;
5089 int exit_code;
5090 pid_t pipe_pid;
5091 PyObject *procObj, *pidObj, *intObj, *fileObj;
5092 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005093#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005094 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005095#endif
5096
Victor Stinnerd6f85422010-05-05 23:33:33 +00005097 /* Close the file handle first, to ensure it can't block the
5098 * child from exiting if it's the last handle.
5099 */
5100 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005101
5102#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005103 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005104#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005105 if (_PyPopenProcs)
5106 {
5107 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5108 (procObj = PyDict_GetItem(_PyPopenProcs,
5109 fileObj)) != NULL &&
5110 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5111 (intObj = PyList_GetItem(procObj,1)) != NULL)
5112 {
5113 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5114 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005115
Victor Stinnerd6f85422010-05-05 23:33:33 +00005116 if (file_count > 1)
5117 {
5118 /* Still other files referencing process */
5119 file_count--;
5120 PyList_SetItem(procObj,1,
5121 PyInt_FromLong((long) file_count));
5122 }
5123 else
5124 {
5125 /* Last file for this process */
5126 if (result != EOF &&
5127 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5128 {
5129 /* extract exit status */
5130 if (WIFEXITED(exit_code))
5131 {
5132 result = WEXITSTATUS(exit_code);
5133 }
5134 else
5135 {
5136 errno = EPIPE;
5137 result = -1;
5138 }
5139 }
5140 else
5141 {
5142 /* Indicate failure - this will cause the file object
5143 * to raise an I/O error and translate the last
5144 * error code from errno. We do have a problem with
5145 * last errors that overlap the normal errno table,
5146 * but that's a consistent problem with the file object.
5147 */
5148 result = -1;
5149 }
5150 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005151
Victor Stinnerd6f85422010-05-05 23:33:33 +00005152 /* Remove this file pointer from dictionary */
5153 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005154
Victor Stinnerd6f85422010-05-05 23:33:33 +00005155 if (PyDict_Size(_PyPopenProcs) == 0)
5156 {
5157 Py_DECREF(_PyPopenProcs);
5158 _PyPopenProcs = NULL;
5159 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160
Victor Stinnerd6f85422010-05-05 23:33:33 +00005161 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005162
Victor Stinnerd6f85422010-05-05 23:33:33 +00005163 Py_XDECREF(fileObj);
5164 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005165
5166#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005167 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005168#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005169 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005170}
5171
5172#endif /* PYCC_??? */
5173
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005174#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005175
5176/*
5177 * Portable 'popen' replacement for Win32.
5178 *
5179 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5180 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005181 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005182 */
5183
5184#include <malloc.h>
5185#include <io.h>
5186#include <fcntl.h>
5187
5188/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5189#define POPEN_1 1
5190#define POPEN_2 2
5191#define POPEN_3 3
5192#define POPEN_4 4
5193
5194static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005195static int _PyPclose(FILE *file);
5196
5197/*
5198 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005199 * for use when retrieving the process exit code. See _PyPclose() below
5200 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005201 */
5202static PyObject *_PyPopenProcs = NULL;
5203
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005204
5205/* popen that works from a GUI.
5206 *
5207 * The result of this function is a pipe (file) connected to the
5208 * processes stdin or stdout, depending on the requested mode.
5209 */
5210
5211static PyObject *
5212posix_popen(PyObject *self, PyObject *args)
5213{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005214 PyObject *f;
5215 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005216
Victor Stinnerd6f85422010-05-05 23:33:33 +00005217 char *cmdstring;
5218 char *mode = "r";
5219 int bufsize = -1;
5220 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5221 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005222
Victor Stinnerd6f85422010-05-05 23:33:33 +00005223 if (*mode == 'r')
5224 tm = _O_RDONLY;
5225 else if (*mode != 'w') {
5226 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5227 return NULL;
5228 } else
5229 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005230
Victor Stinnerd6f85422010-05-05 23:33:33 +00005231 if (bufsize != -1) {
5232 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5233 return NULL;
5234 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005235
Victor Stinnerd6f85422010-05-05 23:33:33 +00005236 if (*(mode+1) == 't')
5237 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5238 else if (*(mode+1) == 'b')
5239 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5240 else
5241 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005242
Victor Stinnerd6f85422010-05-05 23:33:33 +00005243 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005244}
5245
5246/* Variation on win32pipe.popen
5247 *
5248 * The result of this function is a pipe (file) connected to the
5249 * process's stdin, and a pipe connected to the process's stdout.
5250 */
5251
5252static PyObject *
5253win32_popen2(PyObject *self, PyObject *args)
5254{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005255 PyObject *f;
5256 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005257
Victor Stinnerd6f85422010-05-05 23:33:33 +00005258 char *cmdstring;
5259 char *mode = "t";
5260 int bufsize = -1;
5261 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5262 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Victor Stinnerd6f85422010-05-05 23:33:33 +00005264 if (*mode == 't')
5265 tm = _O_TEXT;
5266 else if (*mode != 'b') {
5267 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5268 return NULL;
5269 } else
5270 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005271
Victor Stinnerd6f85422010-05-05 23:33:33 +00005272 if (bufsize != -1) {
5273 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5274 return NULL;
5275 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005276
Victor Stinnerd6f85422010-05-05 23:33:33 +00005277 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005278
Victor Stinnerd6f85422010-05-05 23:33:33 +00005279 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005280}
5281
5282/*
5283 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005284 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005285 * The result of this function is 3 pipes - the process's stdin,
5286 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005287 */
5288
5289static PyObject *
5290win32_popen3(PyObject *self, PyObject *args)
5291{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005292 PyObject *f;
5293 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005294
Victor Stinnerd6f85422010-05-05 23:33:33 +00005295 char *cmdstring;
5296 char *mode = "t";
5297 int bufsize = -1;
5298 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5299 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005300
Victor Stinnerd6f85422010-05-05 23:33:33 +00005301 if (*mode == 't')
5302 tm = _O_TEXT;
5303 else if (*mode != 'b') {
5304 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5305 return NULL;
5306 } else
5307 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005308
Victor Stinnerd6f85422010-05-05 23:33:33 +00005309 if (bufsize != -1) {
5310 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5311 return NULL;
5312 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005313
Victor Stinnerd6f85422010-05-05 23:33:33 +00005314 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005315
Victor Stinnerd6f85422010-05-05 23:33:33 +00005316 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005317}
5318
5319/*
5320 * Variation on win32pipe.popen
5321 *
Tim Peters5aa91602002-01-30 05:46:57 +00005322 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005323 * and stdout+stderr combined as a single pipe.
5324 */
5325
5326static PyObject *
5327win32_popen4(PyObject *self, PyObject *args)
5328{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005329 PyObject *f;
5330 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005331
Victor Stinnerd6f85422010-05-05 23:33:33 +00005332 char *cmdstring;
5333 char *mode = "t";
5334 int bufsize = -1;
5335 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5336 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005337
Victor Stinnerd6f85422010-05-05 23:33:33 +00005338 if (*mode == 't')
5339 tm = _O_TEXT;
5340 else if (*mode != 'b') {
5341 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5342 return NULL;
5343 } else
5344 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005345
Victor Stinnerd6f85422010-05-05 23:33:33 +00005346 if (bufsize != -1) {
5347 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5348 return NULL;
5349 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005350
Victor Stinnerd6f85422010-05-05 23:33:33 +00005351 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005352
Victor Stinnerd6f85422010-05-05 23:33:33 +00005353 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005354}
5355
Mark Hammond08501372001-01-31 07:30:29 +00005356static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005357_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005358 HANDLE hStdin,
5359 HANDLE hStdout,
5360 HANDLE hStderr,
5361 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005362{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005363 PROCESS_INFORMATION piProcInfo;
5364 STARTUPINFO siStartInfo;
5365 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5366 char *s1,*s2, *s3 = " /c ";
5367 const char *szConsoleSpawn = "w9xpopen.exe";
5368 int i;
5369 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005370
Victor Stinnerd6f85422010-05-05 23:33:33 +00005371 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5372 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005373
Victor Stinnerd6f85422010-05-05 23:33:33 +00005374 s1 = (char *)alloca(i);
5375 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5376 /* x < i, so x fits into an integer */
5377 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005378
Victor Stinnerd6f85422010-05-05 23:33:33 +00005379 /* Explicitly check if we are using COMMAND.COM. If we are
5380 * then use the w9xpopen hack.
5381 */
5382 comshell = s1 + x;
5383 while (comshell >= s1 && *comshell != '\\')
5384 --comshell;
5385 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005386
Victor Stinnerd6f85422010-05-05 23:33:33 +00005387 if (GetVersion() < 0x80000000 &&
5388 _stricmp(comshell, "command.com") != 0) {
5389 /* NT/2000 and not using command.com. */
5390 x = i + strlen(s3) + strlen(cmdstring) + 1;
5391 s2 = (char *)alloca(x);
5392 ZeroMemory(s2, x);
5393 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5394 }
5395 else {
5396 /*
5397 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5398 * the workaround listed in KB: Q150956
5399 */
5400 char modulepath[_MAX_PATH];
5401 struct stat statinfo;
5402 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5403 for (x = i = 0; modulepath[i]; i++)
5404 if (modulepath[i] == SEP)
5405 x = i+1;
5406 modulepath[x] = '\0';
5407 /* Create the full-name to w9xpopen, so we can test it exists */
5408 strncat(modulepath,
5409 szConsoleSpawn,
5410 (sizeof(modulepath)/sizeof(modulepath[0]))
5411 -strlen(modulepath));
5412 if (stat(modulepath, &statinfo) != 0) {
5413 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5414 /* Eeek - file-not-found - possibly an embedding
5415 situation - see if we can locate it in sys.prefix
5416 */
5417 strncpy(modulepath,
5418 Py_GetExecPrefix(),
5419 mplen);
5420 modulepath[mplen-1] = '\0';
5421 if (modulepath[strlen(modulepath)-1] != '\\')
5422 strcat(modulepath, "\\");
5423 strncat(modulepath,
5424 szConsoleSpawn,
5425 mplen-strlen(modulepath));
5426 /* No where else to look - raise an easily identifiable
5427 error, rather than leaving Windows to report
5428 "file not found" - as the user is probably blissfully
5429 unaware this shim EXE is used, and it will confuse them.
5430 (well, it confused me for a while ;-)
5431 */
5432 if (stat(modulepath, &statinfo) != 0) {
5433 PyErr_Format(PyExc_RuntimeError,
5434 "Can not locate '%s' which is needed "
5435 "for popen to work with your shell "
5436 "or platform.",
5437 szConsoleSpawn);
5438 return FALSE;
5439 }
5440 }
5441 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5442 strlen(modulepath) +
5443 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005444
Victor Stinnerd6f85422010-05-05 23:33:33 +00005445 s2 = (char *)alloca(x);
5446 ZeroMemory(s2, x);
5447 /* To maintain correct argument passing semantics,
5448 we pass the command-line as it stands, and allow
5449 quoting to be applied. w9xpopen.exe will then
5450 use its argv vector, and re-quote the necessary
5451 args for the ultimate child process.
5452 */
5453 PyOS_snprintf(
5454 s2, x,
5455 "\"%s\" %s%s%s",
5456 modulepath,
5457 s1,
5458 s3,
5459 cmdstring);
5460 /* Not passing CREATE_NEW_CONSOLE has been known to
5461 cause random failures on win9x. Specifically a
5462 dialog:
5463 "Your program accessed mem currently in use at xxx"
5464 and a hopeful warning about the stability of your
5465 system.
5466 Cost is Ctrl+C won't kill children, but anyone
5467 who cares can have a go!
5468 */
5469 dwProcessFlags |= CREATE_NEW_CONSOLE;
5470 }
5471 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005472
Victor Stinnerd6f85422010-05-05 23:33:33 +00005473 /* Could be an else here to try cmd.exe / command.com in the path
5474 Now we'll just error out.. */
5475 else {
5476 PyErr_SetString(PyExc_RuntimeError,
5477 "Cannot locate a COMSPEC environment variable to "
5478 "use as the shell");
5479 return FALSE;
5480 }
Tim Peters5aa91602002-01-30 05:46:57 +00005481
Victor Stinnerd6f85422010-05-05 23:33:33 +00005482 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5483 siStartInfo.cb = sizeof(STARTUPINFO);
5484 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5485 siStartInfo.hStdInput = hStdin;
5486 siStartInfo.hStdOutput = hStdout;
5487 siStartInfo.hStdError = hStderr;
5488 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005489
Victor Stinnerd6f85422010-05-05 23:33:33 +00005490 if (CreateProcess(NULL,
5491 s2,
5492 NULL,
5493 NULL,
5494 TRUE,
5495 dwProcessFlags,
5496 NULL,
5497 NULL,
5498 &siStartInfo,
5499 &piProcInfo) ) {
5500 /* Close the handles now so anyone waiting is woken. */
5501 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005502
Victor Stinnerd6f85422010-05-05 23:33:33 +00005503 /* Return process handle */
5504 *hProcess = piProcInfo.hProcess;
5505 return TRUE;
5506 }
5507 win32_error("CreateProcess", s2);
5508 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005509}
5510
5511/* The following code is based off of KB: Q190351 */
5512
5513static PyObject *
5514_PyPopen(char *cmdstring, int mode, int n)
5515{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005516 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5517 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5518 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005519
Victor Stinnerd6f85422010-05-05 23:33:33 +00005520 SECURITY_ATTRIBUTES saAttr;
5521 BOOL fSuccess;
5522 int fd1, fd2, fd3;
5523 FILE *f1, *f2, *f3;
5524 long file_count;
5525 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005526
Victor Stinnerd6f85422010-05-05 23:33:33 +00005527 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5528 saAttr.bInheritHandle = TRUE;
5529 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005530
Victor Stinnerd6f85422010-05-05 23:33:33 +00005531 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5532 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005533
Victor Stinnerd6f85422010-05-05 23:33:33 +00005534 /* Create new output read handle and the input write handle. Set
5535 * the inheritance properties to FALSE. Otherwise, the child inherits
5536 * these handles; resulting in non-closeable handles to the pipes
5537 * being created. */
5538 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5539 GetCurrentProcess(), &hChildStdinWrDup, 0,
5540 FALSE,
5541 DUPLICATE_SAME_ACCESS);
5542 if (!fSuccess)
5543 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005544
Victor Stinnerd6f85422010-05-05 23:33:33 +00005545 /* Close the inheritable version of ChildStdin
5546 that we're using. */
5547 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005548
Victor Stinnerd6f85422010-05-05 23:33:33 +00005549 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5550 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005551
Victor Stinnerd6f85422010-05-05 23:33:33 +00005552 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5553 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5554 FALSE, DUPLICATE_SAME_ACCESS);
5555 if (!fSuccess)
5556 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005557
Victor Stinnerd6f85422010-05-05 23:33:33 +00005558 /* Close the inheritable version of ChildStdout
5559 that we're using. */
5560 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005561
Victor Stinnerd6f85422010-05-05 23:33:33 +00005562 if (n != POPEN_4) {
5563 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5564 return win32_error("CreatePipe", NULL);
5565 fSuccess = DuplicateHandle(GetCurrentProcess(),
5566 hChildStderrRd,
5567 GetCurrentProcess(),
5568 &hChildStderrRdDup, 0,
5569 FALSE, DUPLICATE_SAME_ACCESS);
5570 if (!fSuccess)
5571 return win32_error("DuplicateHandle", NULL);
5572 /* Close the inheritable version of ChildStdErr that we're using. */
5573 CloseHandle(hChildStderrRd);
5574 }
Tim Peters5aa91602002-01-30 05:46:57 +00005575
Victor Stinnerd6f85422010-05-05 23:33:33 +00005576 switch (n) {
5577 case POPEN_1:
5578 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5579 case _O_WRONLY | _O_TEXT:
5580 /* Case for writing to child Stdin in text mode. */
5581 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5582 f1 = _fdopen(fd1, "w");
5583 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5584 PyFile_SetBufSize(f, 0);
5585 /* We don't care about these pipes anymore, so close them. */
5586 CloseHandle(hChildStdoutRdDup);
5587 CloseHandle(hChildStderrRdDup);
5588 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005589
Victor Stinnerd6f85422010-05-05 23:33:33 +00005590 case _O_RDONLY | _O_TEXT:
5591 /* Case for reading from child Stdout in text mode. */
5592 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5593 f1 = _fdopen(fd1, "r");
5594 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5595 PyFile_SetBufSize(f, 0);
5596 /* We don't care about these pipes anymore, so close them. */
5597 CloseHandle(hChildStdinWrDup);
5598 CloseHandle(hChildStderrRdDup);
5599 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005600
Victor Stinnerd6f85422010-05-05 23:33:33 +00005601 case _O_RDONLY | _O_BINARY:
5602 /* Case for readinig from child Stdout in binary mode. */
5603 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5604 f1 = _fdopen(fd1, "rb");
5605 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5606 PyFile_SetBufSize(f, 0);
5607 /* We don't care about these pipes anymore, so close them. */
5608 CloseHandle(hChildStdinWrDup);
5609 CloseHandle(hChildStderrRdDup);
5610 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005611
Victor Stinnerd6f85422010-05-05 23:33:33 +00005612 case _O_WRONLY | _O_BINARY:
5613 /* Case for writing to child Stdin in binary mode. */
5614 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5615 f1 = _fdopen(fd1, "wb");
5616 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5617 PyFile_SetBufSize(f, 0);
5618 /* We don't care about these pipes anymore, so close them. */
5619 CloseHandle(hChildStdoutRdDup);
5620 CloseHandle(hChildStderrRdDup);
5621 break;
5622 }
5623 file_count = 1;
5624 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005625
Victor Stinnerd6f85422010-05-05 23:33:33 +00005626 case POPEN_2:
5627 case POPEN_4:
5628 {
5629 char *m1, *m2;
5630 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005631
Victor Stinnerd6f85422010-05-05 23:33:33 +00005632 if (mode & _O_TEXT) {
5633 m1 = "r";
5634 m2 = "w";
5635 } else {
5636 m1 = "rb";
5637 m2 = "wb";
5638 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005639
Victor Stinnerd6f85422010-05-05 23:33:33 +00005640 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5641 f1 = _fdopen(fd1, m2);
5642 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5643 f2 = _fdopen(fd2, m1);
5644 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5645 PyFile_SetBufSize(p1, 0);
5646 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5647 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005648
Victor Stinnerd6f85422010-05-05 23:33:33 +00005649 if (n != 4)
5650 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005651
Victor Stinnerd6f85422010-05-05 23:33:33 +00005652 f = PyTuple_Pack(2,p1,p2);
5653 Py_XDECREF(p1);
5654 Py_XDECREF(p2);
5655 file_count = 2;
5656 break;
5657 }
Tim Peters5aa91602002-01-30 05:46:57 +00005658
Victor Stinnerd6f85422010-05-05 23:33:33 +00005659 case POPEN_3:
5660 {
5661 char *m1, *m2;
5662 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005663
Victor Stinnerd6f85422010-05-05 23:33:33 +00005664 if (mode & _O_TEXT) {
5665 m1 = "r";
5666 m2 = "w";
5667 } else {
5668 m1 = "rb";
5669 m2 = "wb";
5670 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005671
Victor Stinnerd6f85422010-05-05 23:33:33 +00005672 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5673 f1 = _fdopen(fd1, m2);
5674 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5675 f2 = _fdopen(fd2, m1);
5676 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5677 f3 = _fdopen(fd3, m1);
5678 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5679 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5680 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5681 PyFile_SetBufSize(p1, 0);
5682 PyFile_SetBufSize(p2, 0);
5683 PyFile_SetBufSize(p3, 0);
5684 f = PyTuple_Pack(3,p1,p2,p3);
5685 Py_XDECREF(p1);
5686 Py_XDECREF(p2);
5687 Py_XDECREF(p3);
5688 file_count = 3;
5689 break;
5690 }
5691 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005692
Victor Stinnerd6f85422010-05-05 23:33:33 +00005693 if (n == POPEN_4) {
5694 if (!_PyPopenCreateProcess(cmdstring,
5695 hChildStdinRd,
5696 hChildStdoutWr,
5697 hChildStdoutWr,
5698 &hProcess))
5699 return NULL;
5700 }
5701 else {
5702 if (!_PyPopenCreateProcess(cmdstring,
5703 hChildStdinRd,
5704 hChildStdoutWr,
5705 hChildStderrWr,
5706 &hProcess))
5707 return NULL;
5708 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005709
Victor Stinnerd6f85422010-05-05 23:33:33 +00005710 /*
5711 * Insert the files we've created into the process dictionary
5712 * all referencing the list with the process handle and the
5713 * initial number of files (see description below in _PyPclose).
5714 * Since if _PyPclose later tried to wait on a process when all
5715 * handles weren't closed, it could create a deadlock with the
5716 * child, we spend some energy here to try to ensure that we
5717 * either insert all file handles into the dictionary or none
5718 * at all. It's a little clumsy with the various popen modes
5719 * and variable number of files involved.
5720 */
5721 if (!_PyPopenProcs) {
5722 _PyPopenProcs = PyDict_New();
5723 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005724
Victor Stinnerd6f85422010-05-05 23:33:33 +00005725 if (_PyPopenProcs) {
5726 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5727 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005728
Victor Stinnerd6f85422010-05-05 23:33:33 +00005729 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5730 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005731
Victor Stinnerd6f85422010-05-05 23:33:33 +00005732 procObj = PyList_New(2);
5733 hProcessObj = PyLong_FromVoidPtr(hProcess);
5734 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005735
Victor Stinnerd6f85422010-05-05 23:33:33 +00005736 if (procObj && hProcessObj && intObj) {
5737 PyList_SetItem(procObj,0,hProcessObj);
5738 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005739
Victor Stinnerd6f85422010-05-05 23:33:33 +00005740 fileObj[0] = PyLong_FromVoidPtr(f1);
5741 if (fileObj[0]) {
5742 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5743 fileObj[0],
5744 procObj);
5745 }
5746 if (file_count >= 2) {
5747 fileObj[1] = PyLong_FromVoidPtr(f2);
5748 if (fileObj[1]) {
5749 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5750 fileObj[1],
5751 procObj);
5752 }
5753 }
5754 if (file_count >= 3) {
5755 fileObj[2] = PyLong_FromVoidPtr(f3);
5756 if (fileObj[2]) {
5757 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5758 fileObj[2],
5759 procObj);
5760 }
5761 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005762
Victor Stinnerd6f85422010-05-05 23:33:33 +00005763 if (ins_rc[0] < 0 || !fileObj[0] ||
5764 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5765 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5766 /* Something failed - remove any dictionary
5767 * entries that did make it.
5768 */
5769 if (!ins_rc[0] && fileObj[0]) {
5770 PyDict_DelItem(_PyPopenProcs,
5771 fileObj[0]);
5772 }
5773 if (!ins_rc[1] && fileObj[1]) {
5774 PyDict_DelItem(_PyPopenProcs,
5775 fileObj[1]);
5776 }
5777 if (!ins_rc[2] && fileObj[2]) {
5778 PyDict_DelItem(_PyPopenProcs,
5779 fileObj[2]);
5780 }
5781 }
5782 }
Tim Peters5aa91602002-01-30 05:46:57 +00005783
Victor Stinnerd6f85422010-05-05 23:33:33 +00005784 /*
5785 * Clean up our localized references for the dictionary keys
5786 * and value since PyDict_SetItem will Py_INCREF any copies
5787 * that got placed in the dictionary.
5788 */
5789 Py_XDECREF(procObj);
5790 Py_XDECREF(fileObj[0]);
5791 Py_XDECREF(fileObj[1]);
5792 Py_XDECREF(fileObj[2]);
5793 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005794
Victor Stinnerd6f85422010-05-05 23:33:33 +00005795 /* Child is launched. Close the parents copy of those pipe
5796 * handles that only the child should have open. You need to
5797 * make sure that no handles to the write end of the output pipe
5798 * are maintained in this process or else the pipe will not close
5799 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005800
Victor Stinnerd6f85422010-05-05 23:33:33 +00005801 if (!CloseHandle(hChildStdinRd))
5802 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005803
Victor Stinnerd6f85422010-05-05 23:33:33 +00005804 if (!CloseHandle(hChildStdoutWr))
5805 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005806
Victor Stinnerd6f85422010-05-05 23:33:33 +00005807 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5808 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005809
Victor Stinnerd6f85422010-05-05 23:33:33 +00005810 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005811}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005812
5813/*
5814 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5815 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005816 *
5817 * This function uses the _PyPopenProcs dictionary in order to map the
5818 * input file pointer to information about the process that was
5819 * originally created by the popen* call that created the file pointer.
5820 * The dictionary uses the file pointer as a key (with one entry
5821 * inserted for each file returned by the original popen* call) and a
5822 * single list object as the value for all files from a single call.
5823 * The list object contains the Win32 process handle at [0], and a file
5824 * count at [1], which is initialized to the total number of file
5825 * handles using that list.
5826 *
5827 * This function closes whichever handle it is passed, and decrements
5828 * the file count in the dictionary for the process handle pointed to
5829 * by this file. On the last close (when the file count reaches zero),
5830 * this function will wait for the child process and then return its
5831 * exit code as the result of the close() operation. This permits the
5832 * files to be closed in any order - it is always the close() of the
5833 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005834 *
5835 * NOTE: This function is currently called with the GIL released.
5836 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005837 */
Tim Peters736aa322000-09-01 06:51:24 +00005838
Fredrik Lundh56055a42000-07-23 19:47:12 +00005839static int _PyPclose(FILE *file)
5840{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005841 int result;
5842 DWORD exit_code;
5843 HANDLE hProcess;
5844 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5845 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005846#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005847 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005848#endif
5849
Victor Stinnerd6f85422010-05-05 23:33:33 +00005850 /* Close the file handle first, to ensure it can't block the
5851 * child from exiting if it's the last handle.
5852 */
5853 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005854#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005855 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005856#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005857 if (_PyPopenProcs) {
5858 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5859 (procObj = PyDict_GetItem(_PyPopenProcs,
5860 fileObj)) != NULL &&
5861 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5862 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005863
Victor Stinnerd6f85422010-05-05 23:33:33 +00005864 hProcess = PyLong_AsVoidPtr(hProcessObj);
5865 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005866
Victor Stinnerd6f85422010-05-05 23:33:33 +00005867 if (file_count > 1) {
5868 /* Still other files referencing process */
5869 file_count--;
5870 PyList_SetItem(procObj,1,
5871 PyInt_FromLong(file_count));
5872 } else {
5873 /* Last file for this process */
5874 if (result != EOF &&
5875 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5876 GetExitCodeProcess(hProcess, &exit_code)) {
5877 /* Possible truncation here in 16-bit environments, but
5878 * real exit codes are just the lower byte in any event.
5879 */
5880 result = exit_code;
5881 } else {
5882 /* Indicate failure - this will cause the file object
5883 * to raise an I/O error and translate the last Win32
5884 * error code from errno. We do have a problem with
5885 * last errors that overlap the normal errno table,
5886 * but that's a consistent problem with the file object.
5887 */
5888 if (result != EOF) {
5889 /* If the error wasn't from the fclose(), then
5890 * set errno for the file object error handling.
5891 */
5892 errno = GetLastError();
5893 }
5894 result = -1;
5895 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005896
Victor Stinnerd6f85422010-05-05 23:33:33 +00005897 /* Free up the native handle at this point */
5898 CloseHandle(hProcess);
5899 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005900
Victor Stinnerd6f85422010-05-05 23:33:33 +00005901 /* Remove this file pointer from dictionary */
5902 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005903
Victor Stinnerd6f85422010-05-05 23:33:33 +00005904 if (PyDict_Size(_PyPopenProcs) == 0) {
5905 Py_DECREF(_PyPopenProcs);
5906 _PyPopenProcs = NULL;
5907 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005908
Victor Stinnerd6f85422010-05-05 23:33:33 +00005909 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005910
Victor Stinnerd6f85422010-05-05 23:33:33 +00005911 Py_XDECREF(fileObj);
5912 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005913
Tim Peters736aa322000-09-01 06:51:24 +00005914#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005915 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005916#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005917 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005918}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005919
5920#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005922posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005923{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005924 char *name;
5925 char *mode = "r";
5926 int bufsize = -1;
5927 FILE *fp;
5928 PyObject *f;
5929 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5930 return NULL;
5931 /* Strip mode of binary or text modifiers */
5932 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5933 mode = "r";
5934 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5935 mode = "w";
5936 Py_BEGIN_ALLOW_THREADS
5937 fp = popen(name, mode);
5938 Py_END_ALLOW_THREADS
5939 if (fp == NULL)
5940 return posix_error();
5941 f = PyFile_FromFile(fp, name, mode, pclose);
5942 if (f != NULL)
5943 PyFile_SetBufSize(f, bufsize);
5944 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005945}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005946
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005947#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005948#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005950
Guido van Rossumb6775db1994-08-01 11:34:53 +00005951#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005953"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954Set the current process's user id.");
5955
Barry Warsaw53699e91996-12-10 23:23:01 +00005956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005957posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005958{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005959 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005960 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005961 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005962 if (setuid(uid) < 0)
5963 return posix_error();
5964 Py_INCREF(Py_None);
5965 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005966}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005967#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005969
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005970#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005972"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005973Set the current process's effective user id.");
5974
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005975static PyObject *
5976posix_seteuid (PyObject *self, PyObject *args)
5977{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005978 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005979 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005980 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005981 if (seteuid(euid) < 0) {
5982 return posix_error();
5983 } else {
5984 Py_INCREF(Py_None);
5985 return Py_None;
5986 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005987}
5988#endif /* HAVE_SETEUID */
5989
5990#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993Set the current process's effective group id.");
5994
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005995static PyObject *
5996posix_setegid (PyObject *self, PyObject *args)
5997{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005998 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005999 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006000 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006001 if (setegid(egid) < 0) {
6002 return posix_error();
6003 } else {
6004 Py_INCREF(Py_None);
6005 return Py_None;
6006 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006007}
6008#endif /* HAVE_SETEGID */
6009
6010#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006012"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013Set the current process's real and effective user ids.");
6014
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006015static PyObject *
6016posix_setreuid (PyObject *self, PyObject *args)
6017{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006018 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006019 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6020 _Py_Uid_Converter, &ruid,
6021 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006022 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006023 if (setreuid(ruid, euid) < 0) {
6024 return posix_error();
6025 } else {
6026 Py_INCREF(Py_None);
6027 return Py_None;
6028 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006029}
6030#endif /* HAVE_SETREUID */
6031
6032#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006034"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035Set the current process's real and effective group ids.");
6036
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006037static PyObject *
6038posix_setregid (PyObject *self, PyObject *args)
6039{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006040 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006041 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6042 _Py_Gid_Converter, &rgid,
6043 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006044 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006045 if (setregid(rgid, egid) < 0) {
6046 return posix_error();
6047 } else {
6048 Py_INCREF(Py_None);
6049 return Py_None;
6050 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006051}
6052#endif /* HAVE_SETREGID */
6053
Guido van Rossumb6775db1994-08-01 11:34:53 +00006054#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006055PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006056"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006057Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006058
Barry Warsaw53699e91996-12-10 23:23:01 +00006059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006060posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006061{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006062 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006063 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006064 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006065 if (setgid(gid) < 0)
6066 return posix_error();
6067 Py_INCREF(Py_None);
6068 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006069}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006070#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006071
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006072#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006074"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006076
6077static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006078posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006079{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006080 int i, len;
6081 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006082
Victor Stinnerd6f85422010-05-05 23:33:33 +00006083 if (!PySequence_Check(groups)) {
6084 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6085 return NULL;
6086 }
6087 len = PySequence_Size(groups);
6088 if (len > MAX_GROUPS) {
6089 PyErr_SetString(PyExc_ValueError, "too many groups");
6090 return NULL;
6091 }
6092 for(i = 0; i < len; i++) {
6093 PyObject *elem;
6094 elem = PySequence_GetItem(groups, i);
6095 if (!elem)
6096 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006097 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6098 PyErr_SetString(PyExc_TypeError,
6099 "groups must be integers");
6100 Py_DECREF(elem);
6101 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006102 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006103 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006104 Py_DECREF(elem);
6105 return NULL;
6106 }
6107 }
6108 Py_DECREF(elem);
6109 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006110
Victor Stinnerd6f85422010-05-05 23:33:33 +00006111 if (setgroups(len, grouplist) < 0)
6112 return posix_error();
6113 Py_INCREF(Py_None);
6114 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006115}
6116#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006117
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006118#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006119static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006120wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006121{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006122 PyObject *result;
6123 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006124
Victor Stinnerd6f85422010-05-05 23:33:33 +00006125 if (pid == -1)
6126 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006127
Victor Stinnerd6f85422010-05-05 23:33:33 +00006128 if (struct_rusage == NULL) {
6129 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6130 if (m == NULL)
6131 return NULL;
6132 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6133 Py_DECREF(m);
6134 if (struct_rusage == NULL)
6135 return NULL;
6136 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006137
Victor Stinnerd6f85422010-05-05 23:33:33 +00006138 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6139 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6140 if (!result)
6141 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006142
6143#ifndef doubletime
6144#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6145#endif
6146
Victor Stinnerd6f85422010-05-05 23:33:33 +00006147 PyStructSequence_SET_ITEM(result, 0,
6148 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6149 PyStructSequence_SET_ITEM(result, 1,
6150 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006151#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006152 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6153 SET_INT(result, 2, ru->ru_maxrss);
6154 SET_INT(result, 3, ru->ru_ixrss);
6155 SET_INT(result, 4, ru->ru_idrss);
6156 SET_INT(result, 5, ru->ru_isrss);
6157 SET_INT(result, 6, ru->ru_minflt);
6158 SET_INT(result, 7, ru->ru_majflt);
6159 SET_INT(result, 8, ru->ru_nswap);
6160 SET_INT(result, 9, ru->ru_inblock);
6161 SET_INT(result, 10, ru->ru_oublock);
6162 SET_INT(result, 11, ru->ru_msgsnd);
6163 SET_INT(result, 12, ru->ru_msgrcv);
6164 SET_INT(result, 13, ru->ru_nsignals);
6165 SET_INT(result, 14, ru->ru_nvcsw);
6166 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006167#undef SET_INT
6168
Victor Stinnerd6f85422010-05-05 23:33:33 +00006169 if (PyErr_Occurred()) {
6170 Py_DECREF(result);
6171 return NULL;
6172 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006173
Victor Stinnerd6f85422010-05-05 23:33:33 +00006174 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006175}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006176#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006177
6178#ifdef HAVE_WAIT3
6179PyDoc_STRVAR(posix_wait3__doc__,
6180"wait3(options) -> (pid, status, rusage)\n\n\
6181Wait for completion of a child process.");
6182
6183static PyObject *
6184posix_wait3(PyObject *self, PyObject *args)
6185{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006186 pid_t pid;
6187 int options;
6188 struct rusage ru;
6189 WAIT_TYPE status;
6190 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006191
Victor Stinnerd6f85422010-05-05 23:33:33 +00006192 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6193 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006194
Victor Stinnerd6f85422010-05-05 23:33:33 +00006195 Py_BEGIN_ALLOW_THREADS
6196 pid = wait3(&status, options, &ru);
6197 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006198
Victor Stinnerd6f85422010-05-05 23:33:33 +00006199 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006200}
6201#endif /* HAVE_WAIT3 */
6202
6203#ifdef HAVE_WAIT4
6204PyDoc_STRVAR(posix_wait4__doc__,
6205"wait4(pid, options) -> (pid, status, rusage)\n\n\
6206Wait for completion of a given child process.");
6207
6208static PyObject *
6209posix_wait4(PyObject *self, PyObject *args)
6210{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006211 pid_t pid;
6212 int options;
6213 struct rusage ru;
6214 WAIT_TYPE status;
6215 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006216
Victor Stinnerd6f85422010-05-05 23:33:33 +00006217 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6218 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006219
Victor Stinnerd6f85422010-05-05 23:33:33 +00006220 Py_BEGIN_ALLOW_THREADS
6221 pid = wait4(pid, &status, options, &ru);
6222 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006223
Victor Stinnerd6f85422010-05-05 23:33:33 +00006224 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006225}
6226#endif /* HAVE_WAIT4 */
6227
Guido van Rossumb6775db1994-08-01 11:34:53 +00006228#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006229PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006230"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006232
Barry Warsaw53699e91996-12-10 23:23:01 +00006233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006234posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006235{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006236 pid_t pid;
6237 int options;
6238 WAIT_TYPE status;
6239 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006240
Victor Stinnerd6f85422010-05-05 23:33:33 +00006241 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6242 return NULL;
6243 Py_BEGIN_ALLOW_THREADS
6244 pid = waitpid(pid, &status, options);
6245 Py_END_ALLOW_THREADS
6246 if (pid == -1)
6247 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006248
Victor Stinnerd6f85422010-05-05 23:33:33 +00006249 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006250}
6251
Tim Petersab034fa2002-02-01 11:27:43 +00006252#elif defined(HAVE_CWAIT)
6253
6254/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006258
6259static PyObject *
6260posix_waitpid(PyObject *self, PyObject *args)
6261{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006262 Py_intptr_t pid;
6263 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006264
Victor Stinnerd6f85422010-05-05 23:33:33 +00006265 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6266 return NULL;
6267 Py_BEGIN_ALLOW_THREADS
6268 pid = _cwait(&status, pid, options);
6269 Py_END_ALLOW_THREADS
6270 if (pid == -1)
6271 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006272
Victor Stinnerd6f85422010-05-05 23:33:33 +00006273 /* shift the status left a byte so this is more like the POSIX waitpid */
6274 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006275}
6276#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006277
Guido van Rossumad0ee831995-03-01 10:34:45 +00006278#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006279PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006280"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006282
Barry Warsaw53699e91996-12-10 23:23:01 +00006283static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006284posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006285{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006286 pid_t pid;
6287 WAIT_TYPE status;
6288 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006289
Victor Stinnerd6f85422010-05-05 23:33:33 +00006290 Py_BEGIN_ALLOW_THREADS
6291 pid = wait(&status);
6292 Py_END_ALLOW_THREADS
6293 if (pid == -1)
6294 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006295
Victor Stinnerd6f85422010-05-05 23:33:33 +00006296 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006297}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006298#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006302"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006304
Barry Warsaw53699e91996-12-10 23:23:01 +00006305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006306posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006307{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006309 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006310#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006311#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006312 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006313#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006314 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006315#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006316#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006317}
6318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006319
Guido van Rossumb6775db1994-08-01 11:34:53 +00006320#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006321PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006322"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006324
Barry Warsaw53699e91996-12-10 23:23:01 +00006325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006326posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006327{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006328 PyObject* v;
6329 char buf[MAXPATHLEN];
6330 char *path;
6331 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006332#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006333 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006334#endif
6335
Victor Stinnerd6f85422010-05-05 23:33:33 +00006336 if (!PyArg_ParseTuple(args, "et:readlink",
6337 Py_FileSystemDefaultEncoding, &path))
6338 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006339#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006340 v = PySequence_GetItem(args, 0);
6341 if (v == NULL) {
6342 PyMem_Free(path);
6343 return NULL;
6344 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006345
Victor Stinnerd6f85422010-05-05 23:33:33 +00006346 if (PyUnicode_Check(v)) {
6347 arg_is_unicode = 1;
6348 }
6349 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006350#endif
6351
Victor Stinnerd6f85422010-05-05 23:33:33 +00006352 Py_BEGIN_ALLOW_THREADS
6353 n = readlink(path, buf, (int) sizeof buf);
6354 Py_END_ALLOW_THREADS
6355 if (n < 0)
6356 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006357
Victor Stinnerd6f85422010-05-05 23:33:33 +00006358 PyMem_Free(path);
6359 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006360#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006361 if (arg_is_unicode) {
6362 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006363
Victor Stinnerd6f85422010-05-05 23:33:33 +00006364 w = PyUnicode_FromEncodedObject(v,
6365 Py_FileSystemDefaultEncoding,
6366 "strict");
6367 if (w != NULL) {
6368 Py_DECREF(v);
6369 v = w;
6370 }
6371 else {
6372 /* fall back to the original byte string, as
6373 discussed in patch #683592 */
6374 PyErr_Clear();
6375 }
6376 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006377#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006378 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006379}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006380#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006382
Guido van Rossumb6775db1994-08-01 11:34:53 +00006383#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006384PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006385"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006386Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006387
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006389posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006390{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006391 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006392}
6393#endif /* HAVE_SYMLINK */
6394
6395
6396#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006397#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6398static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006399system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006400{
6401 ULONG value = 0;
6402
6403 Py_BEGIN_ALLOW_THREADS
6404 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6405 Py_END_ALLOW_THREADS
6406
6407 return value;
6408}
6409
6410static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006411posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006412{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006413 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006414 return Py_BuildValue("ddddd",
6415 (double)0 /* t.tms_utime / HZ */,
6416 (double)0 /* t.tms_stime / HZ */,
6417 (double)0 /* t.tms_cutime / HZ */,
6418 (double)0 /* t.tms_cstime / HZ */,
6419 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006420}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006421#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006422#define NEED_TICKS_PER_SECOND
6423static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006424static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006425posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006426{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006427 struct tms t;
6428 clock_t c;
6429 errno = 0;
6430 c = times(&t);
6431 if (c == (clock_t) -1)
6432 return posix_error();
6433 return Py_BuildValue("ddddd",
6434 (double)t.tms_utime / ticks_per_second,
6435 (double)t.tms_stime / ticks_per_second,
6436 (double)t.tms_cutime / ticks_per_second,
6437 (double)t.tms_cstime / ticks_per_second,
6438 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006439}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006440#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006441#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006442
6443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006444#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006445#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006447posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006448{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006449 FILETIME create, exit, kernel, user;
6450 HANDLE hProc;
6451 hProc = GetCurrentProcess();
6452 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6453 /* The fields of a FILETIME structure are the hi and lo part
6454 of a 64-bit value expressed in 100 nanosecond units.
6455 1e7 is one second in such units; 1e-7 the inverse.
6456 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6457 */
6458 return Py_BuildValue(
6459 "ddddd",
6460 (double)(user.dwHighDateTime*429.4967296 +
6461 user.dwLowDateTime*1e-7),
6462 (double)(kernel.dwHighDateTime*429.4967296 +
6463 kernel.dwLowDateTime*1e-7),
6464 (double)0,
6465 (double)0,
6466 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006467}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006468#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006469
6470#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006472"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006473Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006474#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006476
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006477#ifdef HAVE_GETSID
6478PyDoc_STRVAR(posix_getsid__doc__,
6479"getsid(pid) -> sid\n\n\
6480Call the system call getsid().");
6481
6482static PyObject *
6483posix_getsid(PyObject *self, PyObject *args)
6484{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006485 pid_t pid;
6486 int sid;
6487 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6488 return NULL;
6489 sid = getsid(pid);
6490 if (sid < 0)
6491 return posix_error();
6492 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006493}
6494#endif /* HAVE_GETSID */
6495
6496
Guido van Rossumb6775db1994-08-01 11:34:53 +00006497#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006498PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006499"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006500Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006501
Barry Warsaw53699e91996-12-10 23:23:01 +00006502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006503posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006504{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006505 if (setsid() < 0)
6506 return posix_error();
6507 Py_INCREF(Py_None);
6508 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006509}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006510#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006511
Guido van Rossumb6775db1994-08-01 11:34:53 +00006512#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006513PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006514"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Barry Warsaw53699e91996-12-10 23:23:01 +00006517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006519{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006520 pid_t pid;
6521 int pgrp;
6522 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6523 return NULL;
6524 if (setpgid(pid, pgrp) < 0)
6525 return posix_error();
6526 Py_INCREF(Py_None);
6527 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006528}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006529#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006530
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006531
Guido van Rossumb6775db1994-08-01 11:34:53 +00006532#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006534"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006535Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006536
Barry Warsaw53699e91996-12-10 23:23:01 +00006537static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006538posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006539{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006540 int fd;
6541 pid_t pgid;
6542 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6543 return NULL;
6544 pgid = tcgetpgrp(fd);
6545 if (pgid < 0)
6546 return posix_error();
6547 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006548}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006549#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006550
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006551
Guido van Rossumb6775db1994-08-01 11:34:53 +00006552#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006554"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006555Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006556
Barry Warsaw53699e91996-12-10 23:23:01 +00006557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006558posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006559{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006560 int fd;
6561 pid_t pgid;
6562 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6563 return NULL;
6564 if (tcsetpgrp(fd, pgid) < 0)
6565 return posix_error();
6566 Py_INCREF(Py_None);
6567 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006568}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006569#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006570
Guido van Rossum687dd131993-05-17 08:34:16 +00006571/* Functions acting on file descriptors */
6572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006573PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006574"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006575Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006576
Barry Warsaw53699e91996-12-10 23:23:01 +00006577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006578posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006579{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006580 char *file = NULL;
6581 int flag;
6582 int mode = 0777;
6583 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006584
6585#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006586 Py_UNICODE *wpath;
6587 if (PyArg_ParseTuple(args, "ui|i:mkdir", &wpath, &flag, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006588 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006589 fd = _wopen(wpath, flag, mode);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006590 Py_END_ALLOW_THREADS
6591 if (fd < 0)
6592 return posix_error();
6593 return PyInt_FromLong((long)fd);
6594 }
6595 /* Drop the argument parsing error as narrow strings
6596 are also valid. */
6597 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006598#endif
6599
Victor Stinnerd6f85422010-05-05 23:33:33 +00006600 if (!PyArg_ParseTuple(args, "eti|i",
6601 Py_FileSystemDefaultEncoding, &file,
6602 &flag, &mode))
6603 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006604
Victor Stinnerd6f85422010-05-05 23:33:33 +00006605 Py_BEGIN_ALLOW_THREADS
6606 fd = open(file, flag, mode);
6607 Py_END_ALLOW_THREADS
6608 if (fd < 0)
6609 return posix_error_with_allocated_filename(file);
6610 PyMem_Free(file);
6611 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006612}
6613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006615PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006616"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006617Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006618
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006619/*
6620The underscore at end of function name avoids a name clash with the libc
6621function posix_close.
6622*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006623static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006624posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006625{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006626 int fd, res;
6627 if (!PyArg_ParseTuple(args, "i:close", &fd))
6628 return NULL;
6629 if (!_PyVerify_fd(fd))
6630 return posix_error();
6631 Py_BEGIN_ALLOW_THREADS
6632 res = close(fd);
6633 Py_END_ALLOW_THREADS
6634 if (res < 0)
6635 return posix_error();
6636 Py_INCREF(Py_None);
6637 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006638}
6639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006640
Victor Stinnerd6f85422010-05-05 23:33:33 +00006641PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006642"closerange(fd_low, fd_high)\n\n\
6643Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6644
6645static PyObject *
6646posix_closerange(PyObject *self, PyObject *args)
6647{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006648 int fd_from, fd_to, i;
6649 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6650 return NULL;
6651 Py_BEGIN_ALLOW_THREADS
6652 for (i = fd_from; i < fd_to; i++)
6653 if (_PyVerify_fd(i))
6654 close(i);
6655 Py_END_ALLOW_THREADS
6656 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006657}
6658
6659
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006660PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006661"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006663
Barry Warsaw53699e91996-12-10 23:23:01 +00006664static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006665posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006666{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006667 int fd;
6668 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6669 return NULL;
6670 if (!_PyVerify_fd(fd))
6671 return posix_error();
6672 Py_BEGIN_ALLOW_THREADS
6673 fd = dup(fd);
6674 Py_END_ALLOW_THREADS
6675 if (fd < 0)
6676 return posix_error();
6677 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006678}
6679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006681PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006682"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006684
Barry Warsaw53699e91996-12-10 23:23:01 +00006685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006686posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006687{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006688 int fd, fd2, res;
6689 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6690 return NULL;
6691 if (!_PyVerify_fd_dup2(fd, fd2))
6692 return posix_error();
6693 Py_BEGIN_ALLOW_THREADS
6694 res = dup2(fd, fd2);
6695 Py_END_ALLOW_THREADS
6696 if (res < 0)
6697 return posix_error();
6698 Py_INCREF(Py_None);
6699 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006700}
6701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006702
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006703PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006704"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006705Set the current position of a file descriptor.\n\
6706Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006707
Barry Warsaw53699e91996-12-10 23:23:01 +00006708static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006709posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006710{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006711 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006712#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006713 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006714#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006715 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006716#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006717 PyObject *posobj;
6718 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6719 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006720#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006721 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6722 switch (how) {
6723 case 0: how = SEEK_SET; break;
6724 case 1: how = SEEK_CUR; break;
6725 case 2: how = SEEK_END; break;
6726 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006727#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006728
6729#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006730 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006731#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006732 pos = PyLong_Check(posobj) ?
6733 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006734#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006735 if (PyErr_Occurred())
6736 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006737
Victor Stinnerd6f85422010-05-05 23:33:33 +00006738 if (!_PyVerify_fd(fd))
6739 return posix_error();
6740 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006741#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006742 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006743#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006744 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006745#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006746 Py_END_ALLOW_THREADS
6747 if (res < 0)
6748 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006749
6750#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006751 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006752#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006753 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006754#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006755}
6756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006758PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006759"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006760Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006761
Barry Warsaw53699e91996-12-10 23:23:01 +00006762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006763posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006764{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006765 int fd, size, n;
6766 PyObject *buffer;
6767 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6768 return NULL;
6769 if (size < 0) {
6770 errno = EINVAL;
6771 return posix_error();
6772 }
6773 buffer = PyString_FromStringAndSize((char *)NULL, size);
6774 if (buffer == NULL)
6775 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006776 if (!_PyVerify_fd(fd)) {
6777 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006778 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006779 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006780 Py_BEGIN_ALLOW_THREADS
6781 n = read(fd, PyString_AsString(buffer), size);
6782 Py_END_ALLOW_THREADS
6783 if (n < 0) {
6784 Py_DECREF(buffer);
6785 return posix_error();
6786 }
6787 if (n != size)
6788 _PyString_Resize(&buffer, n);
6789 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006790}
6791
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006793PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006794"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006795Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006796
Barry Warsaw53699e91996-12-10 23:23:01 +00006797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006798posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006799{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006800 Py_buffer pbuf;
6801 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006802 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006803
Victor Stinnerd6f85422010-05-05 23:33:33 +00006804 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6805 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006806 if (!_PyVerify_fd(fd)) {
6807 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006808 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006809 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006810 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006811 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006812#if defined(MS_WIN64) || defined(MS_WINDOWS)
6813 if (len > INT_MAX)
6814 len = INT_MAX;
6815 size = write(fd, pbuf.buf, (int)len);
6816#else
6817 size = write(fd, pbuf.buf, len);
6818#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006819 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006820 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006821 if (size < 0)
6822 return posix_error();
6823 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006824}
6825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006827PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006828"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006829Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006830
Barry Warsaw53699e91996-12-10 23:23:01 +00006831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006832posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006833{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006834 int fd;
6835 STRUCT_STAT st;
6836 int res;
6837 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6838 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006839#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006840 /* on OpenVMS we must ensure that all bytes are written to the file */
6841 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006842#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006843 if (!_PyVerify_fd(fd))
6844 return posix_error();
6845 Py_BEGIN_ALLOW_THREADS
6846 res = FSTAT(fd, &st);
6847 Py_END_ALLOW_THREADS
6848 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006849#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006850 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006851#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006852 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006853#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006854 }
Tim Peters5aa91602002-01-30 05:46:57 +00006855
Victor Stinnerd6f85422010-05-05 23:33:33 +00006856 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006857}
6858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006859
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006860PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006861"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006862Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006863
Barry Warsaw53699e91996-12-10 23:23:01 +00006864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006865posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006866{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006867 int fd;
6868 char *orgmode = "r";
6869 int bufsize = -1;
6870 FILE *fp;
6871 PyObject *f;
6872 char *mode;
6873 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6874 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006875
Victor Stinnerd6f85422010-05-05 23:33:33 +00006876 /* Sanitize mode. See fileobject.c */
6877 mode = PyMem_MALLOC(strlen(orgmode)+3);
6878 if (!mode) {
6879 PyErr_NoMemory();
6880 return NULL;
6881 }
6882 strcpy(mode, orgmode);
6883 if (_PyFile_SanitizeMode(mode)) {
6884 PyMem_FREE(mode);
6885 return NULL;
6886 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006887 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006888 PyMem_FREE(mode);
6889 return posix_error();
6890 }
6891#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6892 {
6893 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006894 const char *msg;
6895 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006896 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6897 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006898 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006899 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006900 EISDIR, msg, "<fdopen>");
6901 if (exc) {
6902 PyErr_SetObject(PyExc_IOError, exc);
6903 Py_DECREF(exc);
6904 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006905 return NULL;
6906 }
6907 }
6908#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006909 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006910#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006911 if (mode[0] == 'a') {
6912 /* try to make sure the O_APPEND flag is set */
6913 int flags;
6914 flags = fcntl(fd, F_GETFL);
6915 if (flags != -1)
6916 fcntl(fd, F_SETFL, flags | O_APPEND);
6917 fp = fdopen(fd, mode);
6918 if (fp == NULL && flags != -1)
6919 /* restore old mode if fdopen failed */
6920 fcntl(fd, F_SETFL, flags);
6921 } else {
6922 fp = fdopen(fd, mode);
6923 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006924#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006925 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006926#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006927 Py_END_ALLOW_THREADS
6928 PyMem_FREE(mode);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006929 if (fp == NULL)
6930 return posix_error();
Benjamin Petersonada7d922016-12-03 11:12:51 -08006931 /* The dummy filename used here must be kept in sync with the value
6932 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6933 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
6934 if (f == NULL)
6935 return NULL;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006936 /* We now know we will succeed, so initialize the file object. */
6937 ((PyFileObject *)f)->f_fp = fp;
6938 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006939 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006940}
6941
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006942PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006943"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006944Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006945connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006946
6947static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006948posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006949{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006950 int fd;
6951 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6952 return NULL;
6953 if (!_PyVerify_fd(fd))
6954 return PyBool_FromLong(0);
6955 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006956}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006957
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006958#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006959PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006960"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006961Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006962
Barry Warsaw53699e91996-12-10 23:23:01 +00006963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006964posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006965{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006966#if defined(PYOS_OS2)
6967 HFILE read, write;
6968 APIRET rc;
6969
Victor Stinnerd6f85422010-05-05 23:33:33 +00006970 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006971 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006972 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006973 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006974 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006975
6976 return Py_BuildValue("(ii)", read, write);
6977#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006978#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006979 int fds[2];
6980 int res;
6981 Py_BEGIN_ALLOW_THREADS
6982 res = pipe(fds);
6983 Py_END_ALLOW_THREADS
6984 if (res != 0)
6985 return posix_error();
6986 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006987#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006988 HANDLE read, write;
6989 int read_fd, write_fd;
6990 BOOL ok;
6991 Py_BEGIN_ALLOW_THREADS
6992 ok = CreatePipe(&read, &write, NULL, 0);
6993 Py_END_ALLOW_THREADS
6994 if (!ok)
6995 return win32_error("CreatePipe", NULL);
6996 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6997 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6998 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006999#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007000#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007001}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007002#endif /* HAVE_PIPE */
7003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007004
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007005#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007006PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007007"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007008Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007009
Barry Warsaw53699e91996-12-10 23:23:01 +00007010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007011posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007012{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007013 char *filename;
7014 int mode = 0666;
7015 int res;
7016 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7017 return NULL;
7018 Py_BEGIN_ALLOW_THREADS
7019 res = mkfifo(filename, mode);
7020 Py_END_ALLOW_THREADS
7021 if (res < 0)
7022 return posix_error();
7023 Py_INCREF(Py_None);
7024 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007025}
7026#endif
7027
7028
Neal Norwitz11690112002-07-30 01:08:28 +00007029#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007030PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007031"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007032Create a filesystem node (file, device special file or named pipe)\n\
7033named filename. mode specifies both the permissions to use and the\n\
7034type of node to be created, being combined (bitwise OR) with one of\n\
7035S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007036device defines the newly created device special file (probably using\n\
7037os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007038
7039
7040static PyObject *
7041posix_mknod(PyObject *self, PyObject *args)
7042{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007043 char *filename;
7044 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007045 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007046 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007047 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7048 &filename, &mode,
7049 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007050 return NULL;
7051 Py_BEGIN_ALLOW_THREADS
7052 res = mknod(filename, mode, device);
7053 Py_END_ALLOW_THREADS
7054 if (res < 0)
7055 return posix_error();
7056 Py_INCREF(Py_None);
7057 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007058}
7059#endif
7060
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007061#ifdef HAVE_DEVICE_MACROS
7062PyDoc_STRVAR(posix_major__doc__,
7063"major(device) -> major number\n\
7064Extracts a device major number from a raw device number.");
7065
7066static PyObject *
7067posix_major(PyObject *self, PyObject *args)
7068{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007069 dev_t device;
7070 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007071 return NULL;
7072 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007073}
7074
7075PyDoc_STRVAR(posix_minor__doc__,
7076"minor(device) -> minor number\n\
7077Extracts a device minor number from a raw device number.");
7078
7079static PyObject *
7080posix_minor(PyObject *self, PyObject *args)
7081{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007082 dev_t device;
7083 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007084 return NULL;
7085 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007086}
7087
7088PyDoc_STRVAR(posix_makedev__doc__,
7089"makedev(major, minor) -> device number\n\
7090Composes a raw device number from the major and minor device numbers.");
7091
7092static PyObject *
7093posix_makedev(PyObject *self, PyObject *args)
7094{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007095 int major, minor;
7096 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7097 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007098 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007099}
7100#endif /* device macros */
7101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007102
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007103#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007104PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007105"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007106Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007107
Barry Warsaw53699e91996-12-10 23:23:01 +00007108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007109posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007111 int fd;
7112 off_t length;
7113 int res;
7114 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007115
Victor Stinnerd6f85422010-05-05 23:33:33 +00007116 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7117 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007118
7119#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007120 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007121#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007122 length = PyLong_Check(lenobj) ?
7123 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007124#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007125 if (PyErr_Occurred())
7126 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007127
Victor Stinnerd6f85422010-05-05 23:33:33 +00007128 Py_BEGIN_ALLOW_THREADS
7129 res = ftruncate(fd, length);
7130 Py_END_ALLOW_THREADS
7131 if (res < 0)
7132 return posix_error();
7133 Py_INCREF(Py_None);
7134 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007135}
7136#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007137
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007138#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007139PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007140"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007141Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007142
Fred Drake762e2061999-08-26 17:23:54 +00007143/* Save putenv() parameters as values here, so we can collect them when they
7144 * get re-set with another call for the same key. */
7145static PyObject *posix_putenv_garbage;
7146
Tim Peters5aa91602002-01-30 05:46:57 +00007147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007148posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007149{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007150 char *s1, *s2;
7151 char *newenv;
7152 PyObject *newstr;
7153 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007154
Victor Stinnerd6f85422010-05-05 23:33:33 +00007155 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7156 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007157
7158#if defined(PYOS_OS2)
7159 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7160 APIRET rc;
7161
Guido van Rossumd48f2521997-12-05 22:19:34 +00007162 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7163 if (rc != NO_ERROR)
7164 return os2_error(rc);
7165
7166 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7167 APIRET rc;
7168
Guido van Rossumd48f2521997-12-05 22:19:34 +00007169 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7170 if (rc != NO_ERROR)
7171 return os2_error(rc);
7172 } else {
7173#endif
7174
Victor Stinnerd6f85422010-05-05 23:33:33 +00007175 /* XXX This can leak memory -- not easy to fix :-( */
7176 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007177#ifdef MS_WINDOWS
7178 if (_MAX_ENV < (len - 1)) {
7179 PyErr_Format(PyExc_ValueError,
7180 "the environment variable is longer than %u bytes",
7181 _MAX_ENV);
7182 return NULL;
7183 }
7184#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007185 /* len includes space for a trailing \0; the size arg to
7186 PyString_FromStringAndSize does not count that */
7187 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7188 if (newstr == NULL)
7189 return PyErr_NoMemory();
7190 newenv = PyString_AS_STRING(newstr);
7191 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7192 if (putenv(newenv)) {
7193 Py_DECREF(newstr);
7194 posix_error();
7195 return NULL;
7196 }
7197 /* Install the first arg and newstr in posix_putenv_garbage;
7198 * this will cause previous value to be collected. This has to
7199 * happen after the real putenv() call because the old value
7200 * was still accessible until then. */
7201 if (PyDict_SetItem(posix_putenv_garbage,
7202 PyTuple_GET_ITEM(args, 0), newstr)) {
7203 /* really not much we can do; just leak */
7204 PyErr_Clear();
7205 }
7206 else {
7207 Py_DECREF(newstr);
7208 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007209
7210#if defined(PYOS_OS2)
7211 }
7212#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007213 Py_INCREF(Py_None);
7214 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007215}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007216#endif /* putenv */
7217
Guido van Rossumc524d952001-10-19 01:31:59 +00007218#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007219PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007220"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007221Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007222
7223static PyObject *
7224posix_unsetenv(PyObject *self, PyObject *args)
7225{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007226 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007227#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007228 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007229#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007230
Victor Stinnerd6f85422010-05-05 23:33:33 +00007231 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7232 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007233
Charles-François Natali93a11752011-11-27 13:01:35 +01007234#ifdef HAVE_BROKEN_UNSETENV
7235 unsetenv(s1);
7236#else
Victor Stinner53853c32011-11-22 22:20:13 +01007237 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007238 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007239 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007240#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007241
Victor Stinnerd6f85422010-05-05 23:33:33 +00007242 /* Remove the key from posix_putenv_garbage;
7243 * this will cause it to be collected. This has to
7244 * happen after the real unsetenv() call because the
7245 * old value was still accessible until then.
7246 */
7247 if (PyDict_DelItem(posix_putenv_garbage,
7248 PyTuple_GET_ITEM(args, 0))) {
7249 /* really not much we can do; just leak */
7250 PyErr_Clear();
7251 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007252
Victor Stinnerd6f85422010-05-05 23:33:33 +00007253 Py_INCREF(Py_None);
7254 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007255}
7256#endif /* unsetenv */
7257
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007258PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007259"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007260Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007261
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007263posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007264{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007265 int code;
7266 char *message;
7267 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7268 return NULL;
7269 message = strerror(code);
7270 if (message == NULL) {
7271 PyErr_SetString(PyExc_ValueError,
7272 "strerror() argument out of range");
7273 return NULL;
7274 }
7275 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007276}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007277
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007278
Guido van Rossumc9641791998-08-04 15:26:23 +00007279#ifdef HAVE_SYS_WAIT_H
7280
Fred Drake106c1a02002-04-23 15:58:02 +00007281#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007282PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007283"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007284Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007285
7286static PyObject *
7287posix_WCOREDUMP(PyObject *self, PyObject *args)
7288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007289 WAIT_TYPE status;
7290 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007291
Victor Stinnerd6f85422010-05-05 23:33:33 +00007292 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7293 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007294
Victor Stinnerd6f85422010-05-05 23:33:33 +00007295 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007296}
7297#endif /* WCOREDUMP */
7298
7299#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007300PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007301"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007302Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007303job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007304
7305static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007306posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007307{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007308 WAIT_TYPE status;
7309 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007310
Victor Stinnerd6f85422010-05-05 23:33:33 +00007311 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7312 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007313
Victor Stinnerd6f85422010-05-05 23:33:33 +00007314 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007315}
7316#endif /* WIFCONTINUED */
7317
Guido van Rossumc9641791998-08-04 15:26:23 +00007318#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007319PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007320"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007321Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007322
7323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007324posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007325{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007326 WAIT_TYPE status;
7327 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007328
Victor Stinnerd6f85422010-05-05 23:33:33 +00007329 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7330 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007331
Victor Stinnerd6f85422010-05-05 23:33:33 +00007332 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007333}
7334#endif /* WIFSTOPPED */
7335
7336#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007337PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007338"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007339Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007340
7341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007342posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007343{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007344 WAIT_TYPE status;
7345 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007346
Victor Stinnerd6f85422010-05-05 23:33:33 +00007347 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7348 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007349
Victor Stinnerd6f85422010-05-05 23:33:33 +00007350 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007351}
7352#endif /* WIFSIGNALED */
7353
7354#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007355PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007356"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007357Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007358system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007359
7360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007361posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007362{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007363 WAIT_TYPE status;
7364 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007365
Victor Stinnerd6f85422010-05-05 23:33:33 +00007366 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7367 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007368
Victor Stinnerd6f85422010-05-05 23:33:33 +00007369 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007370}
7371#endif /* WIFEXITED */
7372
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007373#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007375"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007377
7378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007379posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007380{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007381 WAIT_TYPE status;
7382 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007383
Victor Stinnerd6f85422010-05-05 23:33:33 +00007384 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7385 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007386
Victor Stinnerd6f85422010-05-05 23:33:33 +00007387 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007388}
7389#endif /* WEXITSTATUS */
7390
7391#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007392PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007393"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007394Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007395value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007396
7397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007398posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007399{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007400 WAIT_TYPE status;
7401 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007402
Victor Stinnerd6f85422010-05-05 23:33:33 +00007403 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7404 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007405
Victor Stinnerd6f85422010-05-05 23:33:33 +00007406 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007407}
7408#endif /* WTERMSIG */
7409
7410#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007411PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007412"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007413Return the signal that stopped the process that provided\n\
7414the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007415
7416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007417posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007418{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007419 WAIT_TYPE status;
7420 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007421
Victor Stinnerd6f85422010-05-05 23:33:33 +00007422 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7423 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007424
Victor Stinnerd6f85422010-05-05 23:33:33 +00007425 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007426}
7427#endif /* WSTOPSIG */
7428
7429#endif /* HAVE_SYS_WAIT_H */
7430
7431
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007432#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007433#ifdef _SCO_DS
7434/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7435 needed definitions in sys/statvfs.h */
7436#define _SVID3
7437#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007438#include <sys/statvfs.h>
7439
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007440static PyObject*
7441_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007442 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7443 if (v == NULL)
7444 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007445
7446#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007447 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7448 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7449 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7450 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7451 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7452 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7453 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7454 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7455 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7456 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007457#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007458 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7459 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7460 PyStructSequence_SET_ITEM(v, 2,
7461 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7462 PyStructSequence_SET_ITEM(v, 3,
7463 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7464 PyStructSequence_SET_ITEM(v, 4,
7465 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7466 PyStructSequence_SET_ITEM(v, 5,
7467 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7468 PyStructSequence_SET_ITEM(v, 6,
7469 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7470 PyStructSequence_SET_ITEM(v, 7,
7471 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7472 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7473 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007474#endif
7475
Victor Stinnerd6f85422010-05-05 23:33:33 +00007476 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007477}
7478
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007479PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007480"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007481Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007482
7483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007484posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007485{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007486 int fd, res;
7487 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007488
Victor Stinnerd6f85422010-05-05 23:33:33 +00007489 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7490 return NULL;
7491 Py_BEGIN_ALLOW_THREADS
7492 res = fstatvfs(fd, &st);
7493 Py_END_ALLOW_THREADS
7494 if (res != 0)
7495 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007496
Victor Stinnerd6f85422010-05-05 23:33:33 +00007497 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007498}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007499#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007500
7501
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007502#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007503#include <sys/statvfs.h>
7504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007505PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007506"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007507Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007508
7509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007510posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007512 char *path;
7513 int res;
7514 struct statvfs st;
7515 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7516 return NULL;
7517 Py_BEGIN_ALLOW_THREADS
7518 res = statvfs(path, &st);
7519 Py_END_ALLOW_THREADS
7520 if (res != 0)
7521 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007522
Victor Stinnerd6f85422010-05-05 23:33:33 +00007523 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007524}
7525#endif /* HAVE_STATVFS */
7526
7527
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007528#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007529PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007530"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007531Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007532The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007533or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007534
7535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007536posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007537{
7538 PyObject *result = NULL;
7539 char *dir = NULL;
7540 char *pfx = NULL;
7541 char *name;
7542
7543 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007544 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007545
7546 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007547 "tempnam is a potential security risk to your program") < 0)
7548 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007549
Antoine Pitroub0614612011-01-02 20:04:52 +00007550 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7551 "use the tempfile module", 1) < 0)
7552 return NULL;
7553
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007554#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007555 name = _tempnam(dir, pfx);
7556#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007558#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007559 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007560 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007561 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007562 free(name);
7563 return result;
7564}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007565#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566
7567
7568#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007569PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007570"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007571Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572
7573static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007574posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007575{
7576 FILE *fp;
7577
Antoine Pitroub0614612011-01-02 20:04:52 +00007578 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7579 "use the tempfile module", 1) < 0)
7580 return NULL;
7581
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007582 fp = tmpfile();
7583 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007584 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007585 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007586}
7587#endif
7588
7589
7590#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007591PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007592"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007593Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007594
7595static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007596posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007597{
7598 char buffer[L_tmpnam];
7599 char *name;
7600
Skip Montanaro95618b52001-08-18 18:52:10 +00007601 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007602 "tmpnam is a potential security risk to your program") < 0)
7603 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007604
Antoine Pitroub0614612011-01-02 20:04:52 +00007605 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7606 "use the tempfile module", 1) < 0)
7607 return NULL;
7608
Greg Wardb48bc172000-03-01 21:51:56 +00007609#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007610 name = tmpnam_r(buffer);
7611#else
7612 name = tmpnam(buffer);
7613#endif
7614 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007615 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007616#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007617 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007618#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007619 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007620#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007621 );
7622 PyErr_SetObject(PyExc_OSError, err);
7623 Py_XDECREF(err);
7624 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007625 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007626 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007627}
7628#endif
7629
7630
Fred Drakec9680921999-12-13 16:37:25 +00007631/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7632 * It maps strings representing configuration variable names to
7633 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007634 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007635 * rarely-used constants. There are three separate tables that use
7636 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007637 *
7638 * This code is always included, even if none of the interfaces that
7639 * need it are included. The #if hackery needed to avoid it would be
7640 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007641 */
7642struct constdef {
7643 char *name;
7644 long value;
7645};
7646
Fred Drake12c6e2d1999-12-14 21:25:03 +00007647static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007648conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007649 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007650{
7651 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007652 *valuep = PyInt_AS_LONG(arg);
7653 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007654 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007655 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007656 /* look up the value in the table using a binary search */
7657 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007658 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007659 size_t hi = tablesize;
7660 int cmp;
7661 char *confname = PyString_AS_STRING(arg);
7662 while (lo < hi) {
7663 mid = (lo + hi) / 2;
7664 cmp = strcmp(confname, table[mid].name);
7665 if (cmp < 0)
7666 hi = mid;
7667 else if (cmp > 0)
7668 lo = mid + 1;
7669 else {
7670 *valuep = table[mid].value;
7671 return 1;
7672 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007673 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007674 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007675 }
7676 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007677 PyErr_SetString(PyExc_TypeError,
7678 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007679 return 0;
7680}
7681
7682
7683#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7684static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007685#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007686 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007687#endif
7688#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007689 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007690#endif
Fred Drakec9680921999-12-13 16:37:25 +00007691#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007692 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007693#endif
7694#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007696#endif
7697#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007698 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007699#endif
7700#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007701 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007702#endif
7703#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007704 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007705#endif
7706#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007708#endif
7709#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007711#endif
7712#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007713 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007714#endif
7715#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007716 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007717#endif
7718#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007719 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007720#endif
7721#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007722 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007723#endif
7724#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007725 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007726#endif
7727#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007728 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007729#endif
7730#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007731 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007732#endif
7733#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007735#endif
7736};
7737
Fred Drakec9680921999-12-13 16:37:25 +00007738static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007739conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007740{
7741 return conv_confname(arg, valuep, posix_constants_pathconf,
7742 sizeof(posix_constants_pathconf)
7743 / sizeof(struct constdef));
7744}
7745#endif
7746
7747#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007748PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007749"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007750Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007751If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007752
7753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007754posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007755{
7756 PyObject *result = NULL;
7757 int name, fd;
7758
Fred Drake12c6e2d1999-12-14 21:25:03 +00007759 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7760 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007761 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007762
Stefan Krah93f7a322010-11-26 17:35:50 +00007763 errno = 0;
7764 limit = fpathconf(fd, name);
7765 if (limit == -1 && errno != 0)
7766 posix_error();
7767 else
7768 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007769 }
7770 return result;
7771}
7772#endif
7773
7774
7775#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007776PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007777"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007778Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007779If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007780
7781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007782posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007783{
7784 PyObject *result = NULL;
7785 int name;
7786 char *path;
7787
7788 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7789 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007790 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007791
Victor Stinnerd6f85422010-05-05 23:33:33 +00007792 errno = 0;
7793 limit = pathconf(path, name);
7794 if (limit == -1 && errno != 0) {
7795 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007796 /* could be a path or name problem */
7797 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007798 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007799 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007800 }
7801 else
7802 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007803 }
7804 return result;
7805}
7806#endif
7807
7808#ifdef HAVE_CONFSTR
7809static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007810#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007811 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007812#endif
7813#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007814 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007815#endif
7816#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007817 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007818#endif
7819#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007820 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007821#endif
7822#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007823 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007824#endif
Fred Drakec9680921999-12-13 16:37:25 +00007825#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007826 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007827#endif
7828#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007829 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007830#endif
7831#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007832 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007833#endif
7834#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007835 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007836#endif
7837#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007838 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007839#endif
7840#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007841 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007842#endif
7843#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007844 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007845#endif
7846#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007847 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007848#endif
Fred Draked86ed291999-12-15 15:34:33 +00007849#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007850 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007851#endif
Fred Drakec9680921999-12-13 16:37:25 +00007852#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007853 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007854#endif
Fred Draked86ed291999-12-15 15:34:33 +00007855#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007856 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007857#endif
7858#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007859 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007860#endif
7861#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007862 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007863#endif
7864#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007865 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007866#endif
Fred Drakec9680921999-12-13 16:37:25 +00007867#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007868 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007869#endif
7870#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007871 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007872#endif
7873#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007874 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007875#endif
7876#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007877 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007878#endif
7879#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007880 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007881#endif
7882#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007883 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007884#endif
7885#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007886 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007887#endif
7888#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007889 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007890#endif
7891#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007892 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007893#endif
7894#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007895 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007896#endif
7897#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007898 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007899#endif
7900#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007901 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007902#endif
7903#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007904 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007905#endif
7906#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007907 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007908#endif
7909#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007910 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007911#endif
7912#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007913 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007914#endif
Fred Draked86ed291999-12-15 15:34:33 +00007915#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007916 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007917#endif
7918#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007919 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007920#endif
7921#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007922 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007923#endif
7924#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007925 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007926#endif
7927#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007928 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007929#endif
7930#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007931 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007932#endif
7933#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007934 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007935#endif
7936#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007937 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007938#endif
7939#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007940 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007941#endif
7942#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007943 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007944#endif
7945#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007946 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007947#endif
7948#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007949 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007950#endif
7951#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007952 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007953#endif
Fred Drakec9680921999-12-13 16:37:25 +00007954};
7955
7956static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007957conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007958{
7959 return conv_confname(arg, valuep, posix_constants_confstr,
7960 sizeof(posix_constants_confstr)
7961 / sizeof(struct constdef));
7962}
7963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007964PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007965"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007966Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007967
7968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007969posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007970{
7971 PyObject *result = NULL;
7972 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007973 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007974
7975 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007976 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007977
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 errno = 0;
7979 len = confstr(name, buffer, sizeof(buffer));
7980 if (len == 0) {
7981 if (errno) {
7982 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007983 }
7984 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007985 result = Py_None;
7986 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007987 }
7988 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007989 else {
7990 if ((unsigned int)len >= sizeof(buffer)) {
7991 result = PyString_FromStringAndSize(NULL, len-1);
7992 if (result != NULL)
7993 confstr(name, PyString_AS_STRING(result), len);
7994 }
7995 else
7996 result = PyString_FromStringAndSize(buffer, len-1);
7997 }
7998 }
Fred Drakec9680921999-12-13 16:37:25 +00007999 return result;
8000}
8001#endif
8002
8003
8004#ifdef HAVE_SYSCONF
8005static struct constdef posix_constants_sysconf[] = {
8006#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008007 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008008#endif
8009#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008010 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008011#endif
8012#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008013 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008014#endif
8015#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008016 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008017#endif
8018#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008019 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008020#endif
8021#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008022 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008023#endif
8024#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008025 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008026#endif
8027#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008028 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008029#endif
8030#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008031 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008032#endif
8033#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008034 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008035#endif
Fred Draked86ed291999-12-15 15:34:33 +00008036#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008037 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008038#endif
8039#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008040 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008041#endif
Fred Drakec9680921999-12-13 16:37:25 +00008042#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008043 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008044#endif
Fred Drakec9680921999-12-13 16:37:25 +00008045#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008046 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008047#endif
8048#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008049 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008050#endif
8051#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008052 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008053#endif
8054#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008055 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008056#endif
8057#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008058 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008059#endif
Fred Draked86ed291999-12-15 15:34:33 +00008060#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008061 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008062#endif
Fred Drakec9680921999-12-13 16:37:25 +00008063#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008064 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008065#endif
8066#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008067 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008068#endif
8069#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008070 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008071#endif
8072#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008073 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008074#endif
8075#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008076 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008077#endif
Fred Draked86ed291999-12-15 15:34:33 +00008078#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008079 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008080#endif
Fred Drakec9680921999-12-13 16:37:25 +00008081#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008082 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008083#endif
8084#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008085 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008086#endif
8087#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008088 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008089#endif
8090#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008091 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008092#endif
8093#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008094 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008095#endif
8096#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008097 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008098#endif
8099#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008100 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008101#endif
8102#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008103 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008104#endif
8105#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008106 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008107#endif
8108#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008109 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008110#endif
8111#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008112 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008113#endif
8114#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008115 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008116#endif
8117#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008118 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008119#endif
8120#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008121 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008122#endif
8123#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008124 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008125#endif
8126#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008127 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008128#endif
8129#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008130 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008131#endif
8132#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008133 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008134#endif
8135#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008136 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008137#endif
8138#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008139 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008140#endif
8141#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008142 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008143#endif
8144#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008145 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008146#endif
8147#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008148 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008149#endif
Fred Draked86ed291999-12-15 15:34:33 +00008150#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008151 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008152#endif
Fred Drakec9680921999-12-13 16:37:25 +00008153#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008154 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008155#endif
8156#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008157 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008158#endif
8159#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008160 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008161#endif
Fred Draked86ed291999-12-15 15:34:33 +00008162#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008163 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008164#endif
Fred Drakec9680921999-12-13 16:37:25 +00008165#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008166 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008167#endif
Fred Draked86ed291999-12-15 15:34:33 +00008168#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008169 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008170#endif
8171#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008172 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008173#endif
Fred Drakec9680921999-12-13 16:37:25 +00008174#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008175 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008176#endif
8177#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008178 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008179#endif
8180#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008181 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008182#endif
8183#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008184 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008185#endif
Fred Draked86ed291999-12-15 15:34:33 +00008186#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008187 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008188#endif
Fred Drakec9680921999-12-13 16:37:25 +00008189#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008190 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008191#endif
8192#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008193 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008194#endif
8195#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008196 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008197#endif
8198#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008199 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008200#endif
8201#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008202 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008203#endif
8204#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008205 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008206#endif
8207#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008208 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008209#endif
Fred Draked86ed291999-12-15 15:34:33 +00008210#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008211 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008212#endif
Fred Drakec9680921999-12-13 16:37:25 +00008213#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008214 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008215#endif
8216#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008217 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008218#endif
Fred Draked86ed291999-12-15 15:34:33 +00008219#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008220 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008221#endif
Fred Drakec9680921999-12-13 16:37:25 +00008222#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008223 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008224#endif
8225#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008226 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008227#endif
8228#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008229 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008230#endif
8231#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008232 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008233#endif
8234#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008235 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008236#endif
8237#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008238 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008239#endif
8240#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008241 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008242#endif
8243#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008244 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008245#endif
8246#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008247 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008248#endif
Fred Draked86ed291999-12-15 15:34:33 +00008249#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008250 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008251#endif
8252#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008253 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008254#endif
Fred Drakec9680921999-12-13 16:37:25 +00008255#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008256 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008257#endif
8258#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008259 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008260#endif
8261#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008262 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008263#endif
8264#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008265 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008266#endif
8267#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008268 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008269#endif
8270#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008271 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008272#endif
8273#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008274 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008275#endif
8276#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008277 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008278#endif
8279#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008280 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008281#endif
8282#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008283 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008284#endif
8285#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008286 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008287#endif
8288#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008289 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008290#endif
8291#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008292 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008293#endif
8294#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008295 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008296#endif
8297#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008298 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008299#endif
8300#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008301 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008302#endif
8303#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008304 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008305#endif
8306#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008307 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008308#endif
8309#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008310 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008311#endif
8312#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008313 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008314#endif
8315#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008316 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008317#endif
8318#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008319 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008320#endif
8321#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008322 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008323#endif
8324#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008325 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008326#endif
8327#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008328 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008329#endif
8330#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008331 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008332#endif
8333#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008334 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008335#endif
8336#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008337 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008338#endif
8339#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008340 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008341#endif
8342#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008343 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008344#endif
8345#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008346 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008347#endif
8348#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008349 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008350#endif
8351#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008352 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008353#endif
8354#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008355 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008356#endif
8357#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008358 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008359#endif
Fred Draked86ed291999-12-15 15:34:33 +00008360#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008361 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008362#endif
Fred Drakec9680921999-12-13 16:37:25 +00008363#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008364 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008365#endif
8366#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008367 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008368#endif
8369#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008370 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008371#endif
8372#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008373 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008374#endif
8375#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008376 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008377#endif
8378#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008379 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008380#endif
8381#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008382 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008383#endif
8384#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008385 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008386#endif
8387#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008388 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008389#endif
8390#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008391 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008392#endif
8393#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008394 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008395#endif
8396#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008397 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008398#endif
8399#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008400 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008401#endif
8402#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008403 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008404#endif
8405#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008406 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008407#endif
8408#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008409 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008410#endif
8411#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008412 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008413#endif
8414#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008415 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008416#endif
8417#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008418 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008419#endif
8420#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008421 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008422#endif
8423#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008424 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008425#endif
8426#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008427 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008428#endif
8429#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008430 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008431#endif
8432#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008433 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008434#endif
8435#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008436 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008437#endif
8438#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008439 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008440#endif
8441#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008442 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008443#endif
8444#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008445 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008446#endif
8447#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008448 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008449#endif
8450#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008451 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008452#endif
8453#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008454 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008455#endif
8456#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008457 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008458#endif
8459#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008460 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008461#endif
8462#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008463 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008464#endif
8465#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008466 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008467#endif
8468#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008469 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008470#endif
8471#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008472 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008473#endif
8474#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008475 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008476#endif
8477#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008478 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008479#endif
8480#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008481 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008482#endif
8483#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008484 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008485#endif
8486#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008487 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008488#endif
8489#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008490 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008491#endif
8492#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008493 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008494#endif
8495#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008496 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008497#endif
8498};
8499
8500static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008501conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008502{
8503 return conv_confname(arg, valuep, posix_constants_sysconf,
8504 sizeof(posix_constants_sysconf)
8505 / sizeof(struct constdef));
8506}
8507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008508PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008509"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008510Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008511
8512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008513posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008514{
8515 PyObject *result = NULL;
8516 int name;
8517
8518 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008519 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008520
Victor Stinner862490a2010-05-06 00:03:44 +00008521 errno = 0;
8522 value = sysconf(name);
8523 if (value == -1 && errno != 0)
8524 posix_error();
8525 else
8526 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008527 }
8528 return result;
8529}
8530#endif
8531
8532
Fred Drakebec628d1999-12-15 18:31:10 +00008533/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008534 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008535 * the exported dictionaries that are used to publish information about the
8536 * names available on the host platform.
8537 *
8538 * Sorting the table at runtime ensures that the table is properly ordered
8539 * when used, even for platforms we're not able to test on. It also makes
8540 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008541 */
Fred Drakebec628d1999-12-15 18:31:10 +00008542
8543static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008544cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008545{
8546 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008547 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008548 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008549 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008550
8551 return strcmp(c1->name, c2->name);
8552}
8553
8554static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008555setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008556 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008557{
Fred Drakebec628d1999-12-15 18:31:10 +00008558 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008559 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008560 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8561 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008562 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008563 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008564
Barry Warsaw3155db32000-04-13 15:20:40 +00008565 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008566 PyObject *o = PyInt_FromLong(table[i].value);
8567 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8568 Py_XDECREF(o);
8569 Py_DECREF(d);
8570 return -1;
8571 }
8572 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008573 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008574 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008575}
8576
Fred Drakebec628d1999-12-15 18:31:10 +00008577/* Return -1 on failure, 0 on success. */
8578static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008579setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008580{
8581#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008582 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008583 sizeof(posix_constants_pathconf)
8584 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008585 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008586 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008587#endif
8588#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008589 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008590 sizeof(posix_constants_confstr)
8591 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008592 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008593 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008594#endif
8595#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008596 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008597 sizeof(posix_constants_sysconf)
8598 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008599 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008600 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008601#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008602 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008603}
Fred Draked86ed291999-12-15 15:34:33 +00008604
8605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008606PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008607"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008608Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008609in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008610
8611static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008612posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008613{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008614 abort();
8615 /*NOTREACHED*/
8616 Py_FatalError("abort() called from Python code didn't abort!");
8617 return NULL;
8618}
Fred Drakebec628d1999-12-15 18:31:10 +00008619
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008620#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008621PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008622"startfile(filepath [, operation]) - Start a file with its associated\n\
8623application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008624\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008625When \"operation\" is not specified or \"open\", this acts like\n\
8626double-clicking the file in Explorer, or giving the file name as an\n\
8627argument to the DOS \"start\" command: the file is opened with whatever\n\
8628application (if any) its extension is associated.\n\
8629When another \"operation\" is given, it specifies what should be done with\n\
8630the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008631\n\
8632startfile returns as soon as the associated application is launched.\n\
8633There is no option to wait for the application to close, and no way\n\
8634to retrieve the application's exit status.\n\
8635\n\
8636The filepath is relative to the current directory. If you want to use\n\
8637an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008638the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008639
8640static PyObject *
8641win32_startfile(PyObject *self, PyObject *args)
8642{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008643 char *filepath;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008644 Py_UNICODE *wpath;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008645 char *operation = NULL;
8646 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008647
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008648 PyObject *woperation = NULL;
8649 if (!PyArg_ParseTuple(args, "u|s:startfile",
8650 &wpath, &operation)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008651 PyErr_Clear();
8652 goto normal;
8653 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008654
Victor Stinnerd6f85422010-05-05 23:33:33 +00008655 if (operation) {
8656 woperation = PyUnicode_DecodeASCII(operation,
8657 strlen(operation), NULL);
8658 if (!woperation) {
8659 PyErr_Clear();
8660 operation = NULL;
8661 goto normal;
8662 }
8663 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008664
Victor Stinnerd6f85422010-05-05 23:33:33 +00008665 Py_BEGIN_ALLOW_THREADS
8666 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008667 wpath,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008668 NULL, NULL, SW_SHOWNORMAL);
8669 Py_END_ALLOW_THREADS
8670
8671 Py_XDECREF(woperation);
8672 if (rc <= (HINSTANCE)32) {
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008673 PyObject *errval = win32_error_unicode("startfile", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00008674 return errval;
8675 }
8676 Py_INCREF(Py_None);
8677 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008678
8679normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008680 if (!PyArg_ParseTuple(args, "et|s:startfile",
8681 Py_FileSystemDefaultEncoding, &filepath,
8682 &operation))
8683 return NULL;
8684 Py_BEGIN_ALLOW_THREADS
8685 rc = ShellExecute((HWND)0, operation, filepath,
8686 NULL, NULL, SW_SHOWNORMAL);
8687 Py_END_ALLOW_THREADS
8688 if (rc <= (HINSTANCE)32) {
8689 PyObject *errval = win32_error("startfile", filepath);
8690 PyMem_Free(filepath);
8691 return errval;
8692 }
8693 PyMem_Free(filepath);
8694 Py_INCREF(Py_None);
8695 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008696}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008697#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008698
Martin v. Löwis438b5342002-12-27 10:16:42 +00008699#ifdef HAVE_GETLOADAVG
8700PyDoc_STRVAR(posix_getloadavg__doc__,
8701"getloadavg() -> (float, float, float)\n\n\
8702Return the number of processes in the system run queue averaged over\n\
8703the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8704was unobtainable");
8705
8706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008707posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008708{
8709 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008710 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008711 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8712 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008713 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008714 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008715}
8716#endif
8717
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008718PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008719"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008720Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008721
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008722static PyObject *
8723posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008724{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008725 Py_ssize_t size;
8726 PyObject *result;
8727 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008728
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008729 /* Read arguments */
8730 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008731 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008732 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008733 return PyErr_Format(PyExc_ValueError,
8734 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008735 result = PyBytes_FromStringAndSize(NULL, size);
8736 if (result == NULL)
8737 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008738
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008739 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8740 PyBytes_GET_SIZE(result));
8741 if (ret == -1) {
8742 Py_DECREF(result);
8743 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008744 }
8745 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008746}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008747
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008748#ifdef HAVE_SETRESUID
8749PyDoc_STRVAR(posix_setresuid__doc__,
8750"setresuid(ruid, euid, suid)\n\n\
8751Set the current process's real, effective, and saved user ids.");
8752
8753static PyObject*
8754posix_setresuid (PyObject *self, PyObject *args)
8755{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008756 uid_t ruid, euid, suid;
8757 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8758 _Py_Uid_Converter, &ruid,
8759 _Py_Uid_Converter, &euid,
8760 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008761 return NULL;
8762 if (setresuid(ruid, euid, suid) < 0)
8763 return posix_error();
8764 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008765}
8766#endif
8767
8768#ifdef HAVE_SETRESGID
8769PyDoc_STRVAR(posix_setresgid__doc__,
8770"setresgid(rgid, egid, sgid)\n\n\
8771Set the current process's real, effective, and saved group ids.");
8772
8773static PyObject*
8774posix_setresgid (PyObject *self, PyObject *args)
8775{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008776 gid_t rgid, egid, sgid;
8777 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8778 _Py_Gid_Converter, &rgid,
8779 _Py_Gid_Converter, &egid,
8780 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008781 return NULL;
8782 if (setresgid(rgid, egid, sgid) < 0)
8783 return posix_error();
8784 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008785}
8786#endif
8787
8788#ifdef HAVE_GETRESUID
8789PyDoc_STRVAR(posix_getresuid__doc__,
8790"getresuid() -> (ruid, euid, suid)\n\n\
8791Get tuple of the current process's real, effective, and saved user ids.");
8792
8793static PyObject*
8794posix_getresuid (PyObject *self, PyObject *noargs)
8795{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008796 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008797 if (getresuid(&ruid, &euid, &suid) < 0)
8798 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008799 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8800 _PyInt_FromUid(euid),
8801 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008802}
8803#endif
8804
8805#ifdef HAVE_GETRESGID
8806PyDoc_STRVAR(posix_getresgid__doc__,
8807"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008808Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008809
8810static PyObject*
8811posix_getresgid (PyObject *self, PyObject *noargs)
8812{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008813 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008814 if (getresgid(&rgid, &egid, &sgid) < 0)
8815 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008816 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8817 _PyInt_FromGid(egid),
8818 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008819}
8820#endif
8821
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008822static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008823 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008824#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008825 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008826#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008828#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008829 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008830#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008831 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008832#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008834#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008835#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008837#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008838#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008839 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008840#endif /* HAVE_LCHMOD */
8841#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008842 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008843#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008844#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008845 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008846#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008847#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008848 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008849#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008850#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008853#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008854 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008855#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008856#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008857 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008858#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008859 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008860#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008861#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008862#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008864#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8866 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8867 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008868#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008869 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008870#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008871#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008872 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008873#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008874 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8875 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8876 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8877 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008878#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008879 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008880#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008881#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008883#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008884 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008885#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008887#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008888 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8889 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8890 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008891#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008893#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008894 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008895#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008896 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8897 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008898#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008899#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008900 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8901 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008902#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008903 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8904 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008905#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008906#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008907#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008908 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008909#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008910#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008911 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008912#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008913#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008914 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008915#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008916#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008917 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008918#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008919#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008920 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008921#endif /* HAVE_GETEGID */
8922#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008923 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008924#endif /* HAVE_GETEUID */
8925#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008926 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008927#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008928#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008930#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008931 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008932#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008933 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008934#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008935#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008936 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008937#endif /* HAVE_GETPPID */
8938#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008939 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008940#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008941#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008942 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008943#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008944#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008945 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008946#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008947#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008949#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008950#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008951 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008952#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008953#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008954 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008955#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008956 {"popen2", win32_popen2, METH_VARARGS},
8957 {"popen3", win32_popen3, METH_VARARGS},
8958 {"popen4", win32_popen4, METH_VARARGS},
8959 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8960 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008961#else
8962#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"popen2", os2emx_popen2, METH_VARARGS},
8964 {"popen3", os2emx_popen3, METH_VARARGS},
8965 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008966#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008967#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008968#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008969#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008970 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008971#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008972#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008973 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008974#endif /* HAVE_SETEUID */
8975#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008976 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008977#endif /* HAVE_SETEGID */
8978#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008979 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008980#endif /* HAVE_SETREUID */
8981#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008982 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008983#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008984#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008985 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008986#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008987#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008988 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008989#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008990#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008991 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008992#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008993#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008994 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008995#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008996#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008997 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008998#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008999#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009000 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009001#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009002#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009003 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009004#endif /* HAVE_WAIT3 */
9005#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009006 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009007#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009008#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009009 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009010#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009011#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009012 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009013#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009014#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009015 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009016#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009017#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009018 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009019#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009020#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009021 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009022#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009023#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009024 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009025#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009026 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009027 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009028 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9029 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9030 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9031 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9032 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9033 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9034 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9035 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9036 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009037#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009038 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009039#endif
9040#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009041 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009042#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009043#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009044 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009045#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009046#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009047 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9048 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9049 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009050#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009051#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009052 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009053#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009054#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009055 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009056#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009057#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009059#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009060 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009061#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009062 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009063#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009064#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009066#endif
9067#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009069#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009070#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009071#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009072 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009073#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009074#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009075 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009076#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009077#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009078 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009079#endif /* WIFSTOPPED */
9080#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009081 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009082#endif /* WIFSIGNALED */
9083#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009084 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009085#endif /* WIFEXITED */
9086#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009087 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009088#endif /* WEXITSTATUS */
9089#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009090 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009091#endif /* WTERMSIG */
9092#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009093 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009094#endif /* WSTOPSIG */
9095#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009096#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009098#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009099#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009101#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009102#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009103 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009104#endif
9105#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009106 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009107#endif
9108#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009109 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009110#endif
Fred Drakec9680921999-12-13 16:37:25 +00009111#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009112 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009113#endif
9114#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009115 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009116#endif
9117#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009119#endif
9120#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009122#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009123 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009124#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009126 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009127#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009128#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009129 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009130#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009131#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009132 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009133#endif
9134#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009135 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009136#endif
9137#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009139#endif
9140#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009141 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009142#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009143 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009145};
9146
9147
Barry Warsaw4a342091996-12-19 23:50:02 +00009148static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009149ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009150{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009151 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009152}
9153
Guido van Rossumd48f2521997-12-05 22:19:34 +00009154#if defined(PYOS_OS2)
9155/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009156static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009157{
9158 APIRET rc;
9159 ULONG values[QSV_MAX+1];
9160 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009161 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009162
9163 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009164 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009165 Py_END_ALLOW_THREADS
9166
9167 if (rc != NO_ERROR) {
9168 os2_error(rc);
9169 return -1;
9170 }
9171
Fred Drake4d1e64b2002-04-15 19:40:07 +00009172 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9173 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9174 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9175 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9176 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9177 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9178 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009179
9180 switch (values[QSV_VERSION_MINOR]) {
9181 case 0: ver = "2.00"; break;
9182 case 10: ver = "2.10"; break;
9183 case 11: ver = "2.11"; break;
9184 case 30: ver = "3.00"; break;
9185 case 40: ver = "4.00"; break;
9186 case 50: ver = "5.00"; break;
9187 default:
Tim Peters885d4572001-11-28 20:27:42 +00009188 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009189 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009190 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009191 ver = &tmp[0];
9192 }
9193
9194 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009195 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009196 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009197
9198 /* Add Indicator of Which Drive was Used to Boot the System */
9199 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9200 tmp[1] = ':';
9201 tmp[2] = '\0';
9202
Fred Drake4d1e64b2002-04-15 19:40:07 +00009203 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009204}
9205#endif
9206
Barry Warsaw4a342091996-12-19 23:50:02 +00009207static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009208all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009209{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009210#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009211 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009212#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009213#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009214 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009215#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009216#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009217 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009218#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009219#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009220 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009221#endif
Fred Drakec9680921999-12-13 16:37:25 +00009222#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009223 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009224#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009225#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009226 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009227#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009228#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009229 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009230#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009231#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009232 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009233#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009234#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009235 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009236#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009237#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009238 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009239#endif
9240#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009242#endif
9243#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009244 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009245#endif
9246#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009247 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009248#endif
9249#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009250 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009251#endif
9252#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009253 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009254#endif
9255#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009256 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009257#endif
9258#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009259 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009260#endif
9261#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009262 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009263#endif
9264#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009265 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009266#endif
9267#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009268 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009269#endif
9270#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009271 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009272#endif
9273#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009274 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009275#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009276#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009277 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009278#endif
9279#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009280 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009281#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009282#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009283 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009284#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009285#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009286 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009287#endif
9288#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009289 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009290#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009291
Tim Peters5aa91602002-01-30 05:46:57 +00009292/* MS Windows */
9293#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009294 /* Don't inherit in child processes. */
9295 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009296#endif
9297#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009298 /* Optimize for short life (keep in memory). */
9299 /* MS forgot to define this one with a non-underscore form too. */
9300 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009301#endif
9302#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009303 /* Automatically delete when last handle is closed. */
9304 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009305#endif
9306#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009307 /* Optimize for random access. */
9308 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009309#endif
9310#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009311 /* Optimize for sequential access. */
9312 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009313#endif
9314
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009315/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009316#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009317 /* Send a SIGIO signal whenever input or output
9318 becomes available on file descriptor */
9319 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009320#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009321#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009322 /* Direct disk access. */
9323 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009324#endif
9325#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009326 /* Must be a directory. */
9327 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009328#endif
9329#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 /* Do not follow links. */
9331 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009332#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009333#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009334 /* Do not update the access time. */
9335 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009336#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009337
Victor Stinnerd6f85422010-05-05 23:33:33 +00009338 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009339#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009340 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009341#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009342#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009343 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009344#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009345#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009346 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009347#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009348#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009349 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009350#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009351#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009352 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009353#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009354#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009355 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009356#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009357#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009358 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009359#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009360#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009361 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009362#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009363#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009364 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009365#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009366#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009367 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009368#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009369#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009370 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009371#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009372#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009373 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009374#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009375#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009376 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009377#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009378#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009379 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009380#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009381#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009382 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009383#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009384#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009385 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009386#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009387#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009388 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009389#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009390
Guido van Rossum246bc171999-02-01 23:54:31 +00009391#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009392#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009393 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9394 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9395 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9396 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9397 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9398 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9399 if (ins(d, "P_PM", (long)P_PM)) return -1;
9400 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9401 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9402 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9403 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9404 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9405 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9406 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9407 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9408 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9409 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9410 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9411 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9412 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009413#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009414 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9415 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9416 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9417 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9418 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009419#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009420#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009421
Guido van Rossumd48f2521997-12-05 22:19:34 +00009422#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009423 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009424#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009425 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009426}
9427
9428
Tim Peters5aa91602002-01-30 05:46:57 +00009429#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009430#define INITFUNC initnt
9431#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009432
9433#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009434#define INITFUNC initos2
9435#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009436
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009437#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009438#define INITFUNC initposix
9439#define MODNAME "posix"
9440#endif
9441
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009442PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009443INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009444{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009445 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009446
Victor Stinnerd6f85422010-05-05 23:33:33 +00009447 m = Py_InitModule3(MODNAME,
9448 posix_methods,
9449 posix__doc__);
9450 if (m == NULL)
9451 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009452
Victor Stinnerd6f85422010-05-05 23:33:33 +00009453 /* Initialize environ dictionary */
9454 v = convertenviron();
9455 Py_XINCREF(v);
9456 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9457 return;
9458 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009459
Victor Stinnerd6f85422010-05-05 23:33:33 +00009460 if (all_ins(m))
9461 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009462
Victor Stinnerd6f85422010-05-05 23:33:33 +00009463 if (setup_confname_tables(m))
9464 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009465
Victor Stinnerd6f85422010-05-05 23:33:33 +00009466 Py_INCREF(PyExc_OSError);
9467 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009468
Guido van Rossumb3d39562000-01-31 18:41:26 +00009469#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009470 if (posix_putenv_garbage == NULL)
9471 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009472#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009473
Victor Stinnerd6f85422010-05-05 23:33:33 +00009474 if (!initialized) {
9475 stat_result_desc.name = MODNAME ".stat_result";
9476 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9477 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9478 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9479 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9480 structseq_new = StatResultType.tp_new;
9481 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009482
Victor Stinnerd6f85422010-05-05 23:33:33 +00009483 statvfs_result_desc.name = MODNAME ".statvfs_result";
9484 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009485#ifdef NEED_TICKS_PER_SECOND
9486# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009487 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009488# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009489 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009490# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009491 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009492# endif
9493#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009494 }
9495 Py_INCREF((PyObject*) &StatResultType);
9496 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9497 Py_INCREF((PyObject*) &StatVFSResultType);
9498 PyModule_AddObject(m, "statvfs_result",
9499 (PyObject*) &StatVFSResultType);
9500 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009501
9502#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009503 /*
9504 * Step 2 of weak-linking support on Mac OS X.
9505 *
9506 * The code below removes functions that are not available on the
9507 * currently active platform.
9508 *
9509 * This block allow one to use a python binary that was build on
9510 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9511 * OSX 10.4.
9512 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009513#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009514 if (fstatvfs == NULL) {
9515 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9516 return;
9517 }
9518 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009519#endif /* HAVE_FSTATVFS */
9520
9521#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009522 if (statvfs == NULL) {
9523 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9524 return;
9525 }
9526 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009527#endif /* HAVE_STATVFS */
9528
9529# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009530 if (lchown == NULL) {
9531 if (PyObject_DelAttrString(m, "lchown") == -1) {
9532 return;
9533 }
9534 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009535#endif /* HAVE_LCHOWN */
9536
9537
9538#endif /* __APPLE__ */
9539
Guido van Rossumb6775db1994-08-01 11:34:53 +00009540}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009541
9542#ifdef __cplusplus
9543}
9544#endif
9545
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009546