blob: ffeb715c9f156e87ddd75af325e8825e6925d848 [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 }
Serhiy Storchaka9dda2ca2017-06-24 11:49:00 +03003318 /* Search from index 1 because on Windows starting '=' is allowed for
3319 defining hidden environment variables. */
3320 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3321 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3322 goto fail_2;
3323 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003324
3325#if defined(PYOS_OS2)
3326 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3327 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3328#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003329 len = PyString_Size(key) + PyString_Size(val) + 2;
3330 p = PyMem_NEW(char, len);
3331 if (p == NULL) {
3332 PyErr_NoMemory();
3333 goto fail_2;
3334 }
3335 PyOS_snprintf(p, len, "%s=%s", k, v);
3336 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003337#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003338 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003339#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003340 }
3341 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003342
Victor Stinnerd6f85422010-05-05 23:33:33 +00003343 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003344
Victor Stinnerd6f85422010-05-05 23:33:33 +00003345 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003346
Victor Stinnerd6f85422010-05-05 23:33:33 +00003347 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003348
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003349 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003350 while (--envc >= 0)
3351 PyMem_DEL(envlist[envc]);
3352 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003353 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003354 free_string_array(argvlist, lastarg);
3355 Py_XDECREF(vals);
3356 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003357 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003358 PyMem_Free(path);
3359 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003360}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003361#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003363
Guido van Rossuma1065681999-01-25 23:20:23 +00003364#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003365PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003366"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003367Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003368\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003369 mode: mode of process creation\n\
3370 path: path of executable file\n\
3371 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003372
3373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003374posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003375{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003376 char *path;
3377 PyObject *argv;
3378 char **argvlist;
3379 int mode, i;
3380 Py_ssize_t argc;
3381 Py_intptr_t spawnval;
3382 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003383
Victor Stinnerd6f85422010-05-05 23:33:33 +00003384 /* spawnv has three arguments: (mode, path, argv), where
3385 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003386
Victor Stinnerd6f85422010-05-05 23:33:33 +00003387 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3388 Py_FileSystemDefaultEncoding,
3389 &path, &argv))
3390 return NULL;
3391 if (PyList_Check(argv)) {
3392 argc = PyList_Size(argv);
3393 getitem = PyList_GetItem;
3394 }
3395 else if (PyTuple_Check(argv)) {
3396 argc = PyTuple_Size(argv);
3397 getitem = PyTuple_GetItem;
3398 }
3399 else {
3400 PyErr_SetString(PyExc_TypeError,
3401 "spawnv() arg 2 must be a tuple or list");
3402 PyMem_Free(path);
3403 return NULL;
3404 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003405
Victor Stinnerd6f85422010-05-05 23:33:33 +00003406 argvlist = PyMem_NEW(char *, argc+1);
3407 if (argvlist == NULL) {
3408 PyMem_Free(path);
3409 return PyErr_NoMemory();
3410 }
3411 for (i = 0; i < argc; i++) {
3412 if (!PyArg_Parse((*getitem)(argv, i), "et",
3413 Py_FileSystemDefaultEncoding,
3414 &argvlist[i])) {
3415 free_string_array(argvlist, i);
3416 PyErr_SetString(
3417 PyExc_TypeError,
3418 "spawnv() arg 2 must contain only strings");
3419 PyMem_Free(path);
3420 return NULL;
3421 }
3422 }
3423 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003424
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003425#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003426 Py_BEGIN_ALLOW_THREADS
3427 spawnval = spawnv(mode, path, argvlist);
3428 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003429#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003430 if (mode == _OLD_P_OVERLAY)
3431 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003432
Victor Stinnerd6f85422010-05-05 23:33:33 +00003433 Py_BEGIN_ALLOW_THREADS
3434 spawnval = _spawnv(mode, path, argvlist);
3435 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003436#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003437
Victor Stinnerd6f85422010-05-05 23:33:33 +00003438 free_string_array(argvlist, argc);
3439 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003440
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 if (spawnval == -1)
3442 return posix_error();
3443 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003444#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003445 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003446#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003447 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003448#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003449}
3450
3451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003452PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003453"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003454Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003455\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003456 mode: mode of process creation\n\
3457 path: path of executable file\n\
3458 args: tuple or list of arguments\n\
3459 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003460
3461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003462posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003463{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003464 char *path;
3465 PyObject *argv, *env;
3466 char **argvlist;
3467 char **envlist;
3468 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3469 int mode, pos, envc;
3470 Py_ssize_t argc, i;
3471 Py_intptr_t spawnval;
3472 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3473 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003474
Victor Stinnerd6f85422010-05-05 23:33:33 +00003475 /* spawnve has four arguments: (mode, path, argv, env), where
3476 argv is a list or tuple of strings and env is a dictionary
3477 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003478
Victor Stinnerd6f85422010-05-05 23:33:33 +00003479 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3480 Py_FileSystemDefaultEncoding,
3481 &path, &argv, &env))
3482 return NULL;
3483 if (PyList_Check(argv)) {
3484 argc = PyList_Size(argv);
3485 getitem = PyList_GetItem;
3486 }
3487 else if (PyTuple_Check(argv)) {
3488 argc = PyTuple_Size(argv);
3489 getitem = PyTuple_GetItem;
3490 }
3491 else {
3492 PyErr_SetString(PyExc_TypeError,
3493 "spawnve() arg 2 must be a tuple or list");
3494 goto fail_0;
3495 }
3496 if (!PyMapping_Check(env)) {
3497 PyErr_SetString(PyExc_TypeError,
3498 "spawnve() arg 3 must be a mapping object");
3499 goto fail_0;
3500 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003501
Victor Stinnerd6f85422010-05-05 23:33:33 +00003502 argvlist = PyMem_NEW(char *, argc+1);
3503 if (argvlist == NULL) {
3504 PyErr_NoMemory();
3505 goto fail_0;
3506 }
3507 for (i = 0; i < argc; i++) {
3508 if (!PyArg_Parse((*getitem)(argv, i),
3509 "et;spawnve() arg 2 must contain only strings",
3510 Py_FileSystemDefaultEncoding,
3511 &argvlist[i]))
3512 {
3513 lastarg = i;
3514 goto fail_1;
3515 }
3516 }
3517 lastarg = argc;
3518 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003519
Victor Stinnerd6f85422010-05-05 23:33:33 +00003520 i = PyMapping_Size(env);
3521 if (i < 0)
3522 goto fail_1;
3523 envlist = PyMem_NEW(char *, i + 1);
3524 if (envlist == NULL) {
3525 PyErr_NoMemory();
3526 goto fail_1;
3527 }
3528 envc = 0;
3529 keys = PyMapping_Keys(env);
3530 vals = PyMapping_Values(env);
3531 if (!keys || !vals)
3532 goto fail_2;
3533 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3534 PyErr_SetString(PyExc_TypeError,
3535 "spawnve(): env.keys() or env.values() is not a list");
3536 goto fail_2;
3537 }
Tim Peters5aa91602002-01-30 05:46:57 +00003538
Victor Stinnerd6f85422010-05-05 23:33:33 +00003539 for (pos = 0; pos < i; pos++) {
3540 char *p, *k, *v;
3541 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003542
Victor Stinnerd6f85422010-05-05 23:33:33 +00003543 key = PyList_GetItem(keys, pos);
3544 val = PyList_GetItem(vals, pos);
3545 if (!key || !val)
3546 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003547
Victor Stinnerd6f85422010-05-05 23:33:33 +00003548 if (!PyArg_Parse(
3549 key,
3550 "s;spawnve() arg 3 contains a non-string key",
3551 &k) ||
3552 !PyArg_Parse(
3553 val,
3554 "s;spawnve() arg 3 contains a non-string value",
3555 &v))
3556 {
3557 goto fail_2;
3558 }
3559 len = PyString_Size(key) + PyString_Size(val) + 2;
3560 p = PyMem_NEW(char, len);
3561 if (p == NULL) {
3562 PyErr_NoMemory();
3563 goto fail_2;
3564 }
3565 PyOS_snprintf(p, len, "%s=%s", k, v);
3566 envlist[envc++] = p;
3567 }
3568 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003569
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003570#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003571 Py_BEGIN_ALLOW_THREADS
3572 spawnval = spawnve(mode, path, argvlist, envlist);
3573 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003574#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003575 if (mode == _OLD_P_OVERLAY)
3576 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003577
Victor Stinnerd6f85422010-05-05 23:33:33 +00003578 Py_BEGIN_ALLOW_THREADS
3579 spawnval = _spawnve(mode, path, argvlist, envlist);
3580 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003581#endif
Tim Peters25059d32001-12-07 20:35:43 +00003582
Victor Stinnerd6f85422010-05-05 23:33:33 +00003583 if (spawnval == -1)
3584 (void) posix_error();
3585 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003586#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003587 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003588#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003589 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003590#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003591
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003592 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003593 while (--envc >= 0)
3594 PyMem_DEL(envlist[envc]);
3595 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003596 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003597 free_string_array(argvlist, lastarg);
3598 Py_XDECREF(vals);
3599 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003600 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003601 PyMem_Free(path);
3602 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003603}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003604
3605/* OS/2 supports spawnvp & spawnvpe natively */
3606#if defined(PYOS_OS2)
3607PyDoc_STRVAR(posix_spawnvp__doc__,
3608"spawnvp(mode, file, args)\n\n\
3609Execute the program 'file' in a new process, using the environment\n\
3610search path to find the file.\n\
3611\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003612 mode: mode of process creation\n\
3613 file: executable file name\n\
3614 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003615
3616static PyObject *
3617posix_spawnvp(PyObject *self, PyObject *args)
3618{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003619 char *path;
3620 PyObject *argv;
3621 char **argvlist;
3622 int mode, i, argc;
3623 Py_intptr_t spawnval;
3624 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003625
Victor Stinnerd6f85422010-05-05 23:33:33 +00003626 /* spawnvp has three arguments: (mode, path, argv), where
3627 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003628
Victor Stinnerd6f85422010-05-05 23:33:33 +00003629 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3630 Py_FileSystemDefaultEncoding,
3631 &path, &argv))
3632 return NULL;
3633 if (PyList_Check(argv)) {
3634 argc = PyList_Size(argv);
3635 getitem = PyList_GetItem;
3636 }
3637 else if (PyTuple_Check(argv)) {
3638 argc = PyTuple_Size(argv);
3639 getitem = PyTuple_GetItem;
3640 }
3641 else {
3642 PyErr_SetString(PyExc_TypeError,
3643 "spawnvp() arg 2 must be a tuple or list");
3644 PyMem_Free(path);
3645 return NULL;
3646 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003647
Victor Stinnerd6f85422010-05-05 23:33:33 +00003648 argvlist = PyMem_NEW(char *, argc+1);
3649 if (argvlist == NULL) {
3650 PyMem_Free(path);
3651 return PyErr_NoMemory();
3652 }
3653 for (i = 0; i < argc; i++) {
3654 if (!PyArg_Parse((*getitem)(argv, i), "et",
3655 Py_FileSystemDefaultEncoding,
3656 &argvlist[i])) {
3657 free_string_array(argvlist, i);
3658 PyErr_SetString(
3659 PyExc_TypeError,
3660 "spawnvp() arg 2 must contain only strings");
3661 PyMem_Free(path);
3662 return NULL;
3663 }
3664 }
3665 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003666
Victor Stinnerd6f85422010-05-05 23:33:33 +00003667 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003668#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003669 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003670#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003671 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003672#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003673 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003674
Victor Stinnerd6f85422010-05-05 23:33:33 +00003675 free_string_array(argvlist, argc);
3676 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003677
Victor Stinnerd6f85422010-05-05 23:33:33 +00003678 if (spawnval == -1)
3679 return posix_error();
3680 else
3681 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003682}
3683
3684
3685PyDoc_STRVAR(posix_spawnvpe__doc__,
3686"spawnvpe(mode, file, args, env)\n\n\
3687Execute the program 'file' in a new process, using the environment\n\
3688search path to find the file.\n\
3689\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003690 mode: mode of process creation\n\
3691 file: executable file name\n\
3692 args: tuple or list of arguments\n\
3693 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003694
3695static PyObject *
3696posix_spawnvpe(PyObject *self, PyObject *args)
3697{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003698 char *path;
3699 PyObject *argv, *env;
3700 char **argvlist;
3701 char **envlist;
3702 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3703 int mode, i, pos, argc, envc;
3704 Py_intptr_t spawnval;
3705 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3706 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003707
Victor Stinnerd6f85422010-05-05 23:33:33 +00003708 /* spawnvpe has four arguments: (mode, path, argv, env), where
3709 argv is a list or tuple of strings and env is a dictionary
3710 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003711
Victor Stinnerd6f85422010-05-05 23:33:33 +00003712 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3713 Py_FileSystemDefaultEncoding,
3714 &path, &argv, &env))
3715 return NULL;
3716 if (PyList_Check(argv)) {
3717 argc = PyList_Size(argv);
3718 getitem = PyList_GetItem;
3719 }
3720 else if (PyTuple_Check(argv)) {
3721 argc = PyTuple_Size(argv);
3722 getitem = PyTuple_GetItem;
3723 }
3724 else {
3725 PyErr_SetString(PyExc_TypeError,
3726 "spawnvpe() arg 2 must be a tuple or list");
3727 goto fail_0;
3728 }
3729 if (!PyMapping_Check(env)) {
3730 PyErr_SetString(PyExc_TypeError,
3731 "spawnvpe() arg 3 must be a mapping object");
3732 goto fail_0;
3733 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003734
Victor Stinnerd6f85422010-05-05 23:33:33 +00003735 argvlist = PyMem_NEW(char *, argc+1);
3736 if (argvlist == NULL) {
3737 PyErr_NoMemory();
3738 goto fail_0;
3739 }
3740 for (i = 0; i < argc; i++) {
3741 if (!PyArg_Parse((*getitem)(argv, i),
3742 "et;spawnvpe() arg 2 must contain only strings",
3743 Py_FileSystemDefaultEncoding,
3744 &argvlist[i]))
3745 {
3746 lastarg = i;
3747 goto fail_1;
3748 }
3749 }
3750 lastarg = argc;
3751 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003752
Victor Stinnerd6f85422010-05-05 23:33:33 +00003753 i = PyMapping_Size(env);
3754 if (i < 0)
3755 goto fail_1;
3756 envlist = PyMem_NEW(char *, i + 1);
3757 if (envlist == NULL) {
3758 PyErr_NoMemory();
3759 goto fail_1;
3760 }
3761 envc = 0;
3762 keys = PyMapping_Keys(env);
3763 vals = PyMapping_Values(env);
3764 if (!keys || !vals)
3765 goto fail_2;
3766 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3767 PyErr_SetString(PyExc_TypeError,
3768 "spawnvpe(): env.keys() or env.values() is not a list");
3769 goto fail_2;
3770 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003771
Victor Stinnerd6f85422010-05-05 23:33:33 +00003772 for (pos = 0; pos < i; pos++) {
3773 char *p, *k, *v;
3774 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003775
Victor Stinnerd6f85422010-05-05 23:33:33 +00003776 key = PyList_GetItem(keys, pos);
3777 val = PyList_GetItem(vals, pos);
3778 if (!key || !val)
3779 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003780
Victor Stinnerd6f85422010-05-05 23:33:33 +00003781 if (!PyArg_Parse(
3782 key,
3783 "s;spawnvpe() arg 3 contains a non-string key",
3784 &k) ||
3785 !PyArg_Parse(
3786 val,
3787 "s;spawnvpe() arg 3 contains a non-string value",
3788 &v))
3789 {
3790 goto fail_2;
3791 }
3792 len = PyString_Size(key) + PyString_Size(val) + 2;
3793 p = PyMem_NEW(char, len);
3794 if (p == NULL) {
3795 PyErr_NoMemory();
3796 goto fail_2;
3797 }
3798 PyOS_snprintf(p, len, "%s=%s", k, v);
3799 envlist[envc++] = p;
3800 }
3801 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003802
Victor Stinnerd6f85422010-05-05 23:33:33 +00003803 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003804#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003805 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003806#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003807 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003808#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003809 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003810
Victor Stinnerd6f85422010-05-05 23:33:33 +00003811 if (spawnval == -1)
3812 (void) posix_error();
3813 else
3814 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003815
3816 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003817 while (--envc >= 0)
3818 PyMem_DEL(envlist[envc]);
3819 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003820 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003821 free_string_array(argvlist, lastarg);
3822 Py_XDECREF(vals);
3823 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003824 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003825 PyMem_Free(path);
3826 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003827}
3828#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003829#endif /* HAVE_SPAWNV */
3830
3831
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003832#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003833PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003834"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003835Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3836\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003837Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003838
3839static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003840posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003841{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003842 pid_t pid;
3843 int result = 0;
3844 _PyImport_AcquireLock();
3845 pid = fork1();
3846 if (pid == 0) {
3847 /* child: this clobbers and resets the import lock. */
3848 PyOS_AfterFork();
3849 } else {
3850 /* parent: release the import lock. */
3851 result = _PyImport_ReleaseLock();
3852 }
3853 if (pid == -1)
3854 return posix_error();
3855 if (result < 0) {
3856 /* Don't clobber the OSError if the fork failed. */
3857 PyErr_SetString(PyExc_RuntimeError,
3858 "not holding the import lock");
3859 return NULL;
3860 }
3861 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003862}
3863#endif
3864
3865
Guido van Rossumad0ee831995-03-01 10:34:45 +00003866#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003868"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003869Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003870Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003871
Barry Warsaw53699e91996-12-10 23:23:01 +00003872static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003873posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003874{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003875 pid_t pid;
3876 int result = 0;
3877 _PyImport_AcquireLock();
3878 pid = fork();
3879 if (pid == 0) {
3880 /* child: this clobbers and resets the import lock. */
3881 PyOS_AfterFork();
3882 } else {
3883 /* parent: release the import lock. */
3884 result = _PyImport_ReleaseLock();
3885 }
3886 if (pid == -1)
3887 return posix_error();
3888 if (result < 0) {
3889 /* Don't clobber the OSError if the fork failed. */
3890 PyErr_SetString(PyExc_RuntimeError,
3891 "not holding the import lock");
3892 return NULL;
3893 }
3894 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003896#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003897
Neal Norwitzb59798b2003-03-21 01:43:31 +00003898/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003899/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3900#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003901#define DEV_PTY_FILE "/dev/ptc"
3902#define HAVE_DEV_PTMX
3903#else
3904#define DEV_PTY_FILE "/dev/ptmx"
3905#endif
3906
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003907#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003908#ifdef HAVE_PTY_H
3909#include <pty.h>
3910#else
3911#ifdef HAVE_LIBUTIL_H
3912#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003913#else
3914#ifdef HAVE_UTIL_H
3915#include <util.h>
3916#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003917#endif /* HAVE_LIBUTIL_H */
3918#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003919#ifdef HAVE_STROPTS_H
3920#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003921#endif
3922#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003923
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003924#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003925PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003926"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003927Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003928
3929static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003930posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003931{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003932 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003933#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003934 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003935#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003936#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003937 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003938#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003939 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003940#endif
3941#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003942
Thomas Wouters70c21a12000-07-14 14:28:33 +00003943#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003944 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3945 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003946#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003947 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3948 if (slave_name == NULL)
3949 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003950
Victor Stinnerd6f85422010-05-05 23:33:33 +00003951 slave_fd = open(slave_name, O_RDWR);
3952 if (slave_fd < 0)
3953 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003954#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003955 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3956 if (master_fd < 0)
3957 return posix_error();
3958 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3959 /* change permission of slave */
3960 if (grantpt(master_fd) < 0) {
3961 PyOS_setsig(SIGCHLD, sig_saved);
3962 return posix_error();
3963 }
3964 /* unlock slave */
3965 if (unlockpt(master_fd) < 0) {
3966 PyOS_setsig(SIGCHLD, sig_saved);
3967 return posix_error();
3968 }
3969 PyOS_setsig(SIGCHLD, sig_saved);
3970 slave_name = ptsname(master_fd); /* get name of slave */
3971 if (slave_name == NULL)
3972 return posix_error();
3973 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3974 if (slave_fd < 0)
3975 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003976#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003977 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3978 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003979#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003980 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003981#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003982#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003983#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003984
Victor Stinnerd6f85422010-05-05 23:33:33 +00003985 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003986
Fred Drake8cef4cf2000-06-28 16:40:38 +00003987}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003988#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003989
3990#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003992"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003993Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3994Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003996
3997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003998posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003999{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004000 int master_fd = -1, result = 0;
4001 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004002
Victor Stinnerd6f85422010-05-05 23:33:33 +00004003 _PyImport_AcquireLock();
4004 pid = forkpty(&master_fd, NULL, NULL, NULL);
4005 if (pid == 0) {
4006 /* child: this clobbers and resets the import lock. */
4007 PyOS_AfterFork();
4008 } else {
4009 /* parent: release the import lock. */
4010 result = _PyImport_ReleaseLock();
4011 }
4012 if (pid == -1)
4013 return posix_error();
4014 if (result < 0) {
4015 /* Don't clobber the OSError if the fork failed. */
4016 PyErr_SetString(PyExc_RuntimeError,
4017 "not holding the import lock");
4018 return NULL;
4019 }
4020 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004021}
4022#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004023
Guido van Rossumad0ee831995-03-01 10:34:45 +00004024#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004025PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004026"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004027Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028
Barry Warsaw53699e91996-12-10 23:23:01 +00004029static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004030posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004031{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004032 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004033}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004034#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036
Guido van Rossumad0ee831995-03-01 10:34:45 +00004037#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004038PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004039"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004040Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004041
Barry Warsaw53699e91996-12-10 23:23:01 +00004042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004043posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004044{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004045 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004046}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004047#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Guido van Rossumad0ee831995-03-01 10:34:45 +00004050#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004051PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004052"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004053Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Barry Warsaw53699e91996-12-10 23:23:01 +00004055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004056posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004057{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004058 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004059}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004060#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004062
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004063PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004064"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004065Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004066
Barry Warsaw53699e91996-12-10 23:23:01 +00004067static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004068posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004069{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004070 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004071}
4072
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004073
Fred Drakec9680921999-12-13 16:37:25 +00004074#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004076"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004077Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004078
4079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004080posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004081{
4082 PyObject *result = NULL;
4083
Fred Drakec9680921999-12-13 16:37:25 +00004084#ifdef NGROUPS_MAX
4085#define MAX_GROUPS NGROUPS_MAX
4086#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004087 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004088#define MAX_GROUPS 64
4089#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004090 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004091
Victor Stinner59729ff2011-07-05 11:28:19 +02004092 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004093 * This is a helper variable to store the intermediate result when
4094 * that happens.
4095 *
4096 * To keep the code readable the OSX behaviour is unconditional,
4097 * according to the POSIX spec this should be safe on all unix-y
4098 * systems.
4099 */
4100 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004101 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004102
Ned Deily80743642013-08-01 21:19:09 -07004103#ifdef __APPLE__
4104 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4105 * there are more groups than can fit in grouplist. Therefore, on OS X
4106 * always first call getgroups with length 0 to get the actual number
4107 * of groups.
4108 */
4109 n = getgroups(0, NULL);
4110 if (n < 0) {
4111 return posix_error();
4112 } else if (n <= MAX_GROUPS) {
4113 /* groups will fit in existing array */
4114 alt_grouplist = grouplist;
4115 } else {
4116 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4117 if (alt_grouplist == NULL) {
4118 errno = EINVAL;
4119 return posix_error();
4120 }
4121 }
4122
4123 n = getgroups(n, alt_grouplist);
4124 if (n == -1) {
4125 if (alt_grouplist != grouplist) {
4126 PyMem_Free(alt_grouplist);
4127 }
4128 return posix_error();
4129 }
4130#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004131 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004132 if (n < 0) {
4133 if (errno == EINVAL) {
4134 n = getgroups(0, NULL);
4135 if (n == -1) {
4136 return posix_error();
4137 }
4138 if (n == 0) {
4139 /* Avoid malloc(0) */
4140 alt_grouplist = grouplist;
4141 } else {
4142 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4143 if (alt_grouplist == NULL) {
4144 errno = EINVAL;
4145 return posix_error();
4146 }
4147 n = getgroups(n, alt_grouplist);
4148 if (n == -1) {
4149 PyMem_Free(alt_grouplist);
4150 return posix_error();
4151 }
4152 }
4153 } else {
4154 return posix_error();
4155 }
4156 }
Ned Deily80743642013-08-01 21:19:09 -07004157#endif
4158
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004159 result = PyList_New(n);
4160 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004161 int i;
4162 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004163 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004164 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004165 Py_DECREF(result);
4166 result = NULL;
4167 break;
Fred Drakec9680921999-12-13 16:37:25 +00004168 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004170 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004171 }
4172
4173 if (alt_grouplist != grouplist) {
4174 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004175 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004176
Fred Drakec9680921999-12-13 16:37:25 +00004177 return result;
4178}
4179#endif
4180
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004181#ifdef HAVE_INITGROUPS
4182PyDoc_STRVAR(posix_initgroups__doc__,
4183"initgroups(username, gid) -> None\n\n\
4184Call the system initgroups() to initialize the group access list with all of\n\
4185the groups of which the specified username is a member, plus the specified\n\
4186group id.");
4187
4188static PyObject *
4189posix_initgroups(PyObject *self, PyObject *args)
4190{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004191 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004192#ifdef __APPLE__
4193 int gid;
4194#else
4195 gid_t gid;
4196#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004197
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004198#ifdef __APPLE__
4199 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4200 &gid))
4201#else
4202 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4203 _Py_Gid_Converter, &gid))
4204#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004205 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004206
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004207 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004208 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004209
Victor Stinnerd6f85422010-05-05 23:33:33 +00004210 Py_INCREF(Py_None);
4211 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004212}
4213#endif
4214
Martin v. Löwis606edc12002-06-13 21:09:11 +00004215#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004216PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004217"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004218Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004219
4220static PyObject *
4221posix_getpgid(PyObject *self, PyObject *args)
4222{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004223 pid_t pid, pgid;
4224 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4225 return NULL;
4226 pgid = getpgid(pid);
4227 if (pgid < 0)
4228 return posix_error();
4229 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004230}
4231#endif /* HAVE_GETPGID */
4232
4233
Guido van Rossumb6775db1994-08-01 11:34:53 +00004234#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004235PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004236"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004237Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004238
Barry Warsaw53699e91996-12-10 23:23:01 +00004239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004240posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004241{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004242#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004243 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004244#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004245 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004246#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004247}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004248#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004249
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Guido van Rossumb6775db1994-08-01 11:34:53 +00004251#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004252PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004253"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004254Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255
Barry Warsaw53699e91996-12-10 23:23:01 +00004256static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004257posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004258{
Guido van Rossum64933891994-10-20 21:56:42 +00004259#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004260 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004261#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004262 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004263#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004264 return posix_error();
4265 Py_INCREF(Py_None);
4266 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004267}
4268
Guido van Rossumb6775db1994-08-01 11:34:53 +00004269#endif /* HAVE_SETPGRP */
4270
Guido van Rossumad0ee831995-03-01 10:34:45 +00004271#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004272PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004273"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004274Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004275
Barry Warsaw53699e91996-12-10 23:23:01 +00004276static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004277posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004278{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004279 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004280}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004281#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Fred Drake12c6e2d1999-12-14 21:25:03 +00004284#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004285PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004286"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004287Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004288
4289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004290posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004291{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004292 PyObject *result = NULL;
4293 char *name;
4294 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004295
Victor Stinnerd6f85422010-05-05 23:33:33 +00004296 errno = 0;
4297 name = getlogin();
4298 if (name == NULL) {
4299 if (errno)
4300 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004301 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004302 PyErr_SetString(PyExc_OSError,
4303 "unable to determine login name");
4304 }
4305 else
4306 result = PyString_FromString(name);
4307 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004308
Fred Drake12c6e2d1999-12-14 21:25:03 +00004309 return result;
4310}
4311#endif
4312
Guido van Rossumad0ee831995-03-01 10:34:45 +00004313#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004314PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004315"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004316Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004317
Barry Warsaw53699e91996-12-10 23:23:01 +00004318static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004319posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004320{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004321 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004322}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004323#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004325
Guido van Rossumad0ee831995-03-01 10:34:45 +00004326#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004327PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004328"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004329Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004330
Barry Warsaw53699e91996-12-10 23:23:01 +00004331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004332posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004333{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004334 pid_t pid;
4335 int sig;
4336 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4337 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004338#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004339 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4340 APIRET rc;
4341 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004342 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004343
4344 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4345 APIRET rc;
4346 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004347 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004348
4349 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004350 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004351#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004352 if (kill(pid, sig) == -1)
4353 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004354#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004355 Py_INCREF(Py_None);
4356 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004357}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004358#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004359
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004360#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004361PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004362"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004363Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004364
4365static PyObject *
4366posix_killpg(PyObject *self, PyObject *args)
4367{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004368 int sig;
4369 pid_t pgid;
4370 /* XXX some man pages make the `pgid` parameter an int, others
4371 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4372 take the same type. Moreover, pid_t is always at least as wide as
4373 int (else compilation of this module fails), which is safe. */
4374 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4375 return NULL;
4376 if (killpg(pgid, sig) == -1)
4377 return posix_error();
4378 Py_INCREF(Py_None);
4379 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004380}
4381#endif
4382
Brian Curtine5aa8862010-04-02 23:26:06 +00004383#ifdef MS_WINDOWS
4384PyDoc_STRVAR(win32_kill__doc__,
4385"kill(pid, sig)\n\n\
4386Kill a process with a signal.");
4387
4388static PyObject *
4389win32_kill(PyObject *self, PyObject *args)
4390{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004391 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004392 DWORD pid, sig, err;
4393 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004394
Victor Stinnerd6f85422010-05-05 23:33:33 +00004395 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4396 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004397
Victor Stinnerd6f85422010-05-05 23:33:33 +00004398 /* Console processes which share a common console can be sent CTRL+C or
4399 CTRL+BREAK events, provided they handle said events. */
4400 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4401 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4402 err = GetLastError();
4403 return PyErr_SetFromWindowsErr(err);
4404 }
4405 else
4406 Py_RETURN_NONE;
4407 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004408
Victor Stinnerd6f85422010-05-05 23:33:33 +00004409 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4410 attempt to open and terminate the process. */
4411 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4412 if (handle == NULL) {
4413 err = GetLastError();
4414 return PyErr_SetFromWindowsErr(err);
4415 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004416
Victor Stinnerd6f85422010-05-05 23:33:33 +00004417 if (TerminateProcess(handle, sig) == 0) {
4418 err = GetLastError();
4419 result = PyErr_SetFromWindowsErr(err);
4420 } else {
4421 Py_INCREF(Py_None);
4422 result = Py_None;
4423 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004424
Victor Stinnerd6f85422010-05-05 23:33:33 +00004425 CloseHandle(handle);
4426 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004427}
Brian Curtincaea7e82011-06-08 19:29:53 -05004428
Brian Curtin5446f082011-06-09 10:00:42 -05004429PyDoc_STRVAR(posix__isdir__doc__,
4430"Return true if the pathname refers to an existing directory.");
4431
Brian Curtincaea7e82011-06-08 19:29:53 -05004432static PyObject *
4433posix__isdir(PyObject *self, PyObject *args)
4434{
Brian Curtincaea7e82011-06-08 19:29:53 -05004435 char *path;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004436 Py_UNICODE *wpath;
Brian Curtincaea7e82011-06-08 19:29:53 -05004437 DWORD attributes;
4438
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004439 if (PyArg_ParseTuple(args, "u|:_isdir", &wpath)) {
Brian Curtincaea7e82011-06-08 19:29:53 -05004440 attributes = GetFileAttributesW(wpath);
4441 if (attributes == INVALID_FILE_ATTRIBUTES)
4442 Py_RETURN_FALSE;
4443 goto check;
4444 }
4445 /* Drop the argument parsing error as narrow strings
4446 are also valid. */
4447 PyErr_Clear();
4448
4449 if (!PyArg_ParseTuple(args, "et:_isdir",
4450 Py_FileSystemDefaultEncoding, &path))
4451 return NULL;
4452
4453 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004454 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004455 if (attributes == INVALID_FILE_ATTRIBUTES)
4456 Py_RETURN_FALSE;
4457
4458check:
4459 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4460 Py_RETURN_TRUE;
4461 else
4462 Py_RETURN_FALSE;
4463}
Brian Curtine5aa8862010-04-02 23:26:06 +00004464#endif /* MS_WINDOWS */
4465
Guido van Rossumc0125471996-06-28 18:55:32 +00004466#ifdef HAVE_PLOCK
4467
4468#ifdef HAVE_SYS_LOCK_H
4469#include <sys/lock.h>
4470#endif
4471
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004472PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004473"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004474Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004475
Barry Warsaw53699e91996-12-10 23:23:01 +00004476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004477posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004478{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004479 int op;
4480 if (!PyArg_ParseTuple(args, "i:plock", &op))
4481 return NULL;
4482 if (plock(op) == -1)
4483 return posix_error();
4484 Py_INCREF(Py_None);
4485 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004486}
4487#endif
4488
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004489
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004490#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004492"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004493Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004495#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004496#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004497static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004498async_system(const char *command)
4499{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004500 char errormsg[256], args[1024];
4501 RESULTCODES rcodes;
4502 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004503
Victor Stinnerd6f85422010-05-05 23:33:33 +00004504 char *shell = getenv("COMSPEC");
4505 if (!shell)
4506 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004507
Victor Stinnerd6f85422010-05-05 23:33:33 +00004508 /* avoid overflowing the argument buffer */
4509 if (strlen(shell) + 3 + strlen(command) >= 1024)
4510 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004511
Victor Stinnerd6f85422010-05-05 23:33:33 +00004512 args[0] = '\0';
4513 strcat(args, shell);
4514 strcat(args, "/c ");
4515 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004516
Victor Stinnerd6f85422010-05-05 23:33:33 +00004517 /* execute asynchronously, inheriting the environment */
4518 rc = DosExecPgm(errormsg,
4519 sizeof(errormsg),
4520 EXEC_ASYNC,
4521 args,
4522 NULL,
4523 &rcodes,
4524 shell);
4525 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004526}
4527
Guido van Rossumd48f2521997-12-05 22:19:34 +00004528static FILE *
4529popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004530{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004531 int oldfd, tgtfd;
4532 HFILE pipeh[2];
4533 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004534
Victor Stinnerd6f85422010-05-05 23:33:33 +00004535 /* mode determines which of stdin or stdout is reconnected to
4536 * the pipe to the child
4537 */
4538 if (strchr(mode, 'r') != NULL) {
4539 tgt_fd = 1; /* stdout */
4540 } else if (strchr(mode, 'w')) {
4541 tgt_fd = 0; /* stdin */
4542 } else {
4543 *err = ERROR_INVALID_ACCESS;
4544 return NULL;
4545 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004546
Victor Stinnerd6f85422010-05-05 23:33:33 +00004547 /* setup the pipe */
4548 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4549 *err = rc;
4550 return NULL;
4551 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004552
Victor Stinnerd6f85422010-05-05 23:33:33 +00004553 /* prevent other threads accessing stdio */
4554 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004555
Victor Stinnerd6f85422010-05-05 23:33:33 +00004556 /* reconnect stdio and execute child */
4557 oldfd = dup(tgtfd);
4558 close(tgtfd);
4559 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4560 DosClose(pipeh[tgtfd]);
4561 rc = async_system(command);
4562 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004563
Victor Stinnerd6f85422010-05-05 23:33:33 +00004564 /* restore stdio */
4565 dup2(oldfd, tgtfd);
4566 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004567
Victor Stinnerd6f85422010-05-05 23:33:33 +00004568 /* allow other threads access to stdio */
4569 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004570
Victor Stinnerd6f85422010-05-05 23:33:33 +00004571 /* if execution of child was successful return file stream */
4572 if (rc == NO_ERROR)
4573 return fdopen(pipeh[1 - tgtfd], mode);
4574 else {
4575 DosClose(pipeh[1 - tgtfd]);
4576 *err = rc;
4577 return NULL;
4578 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004579}
4580
4581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004582posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004583{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004584 char *name;
4585 char *mode = "r";
4586 int err, bufsize = -1;
4587 FILE *fp;
4588 PyObject *f;
4589 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4590 return NULL;
4591 Py_BEGIN_ALLOW_THREADS
4592 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4593 Py_END_ALLOW_THREADS
4594 if (fp == NULL)
4595 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004596
Victor Stinnerd6f85422010-05-05 23:33:33 +00004597 f = PyFile_FromFile(fp, name, mode, fclose);
4598 if (f != NULL)
4599 PyFile_SetBufSize(f, bufsize);
4600 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004601}
4602
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004603#elif defined(PYCC_GCC)
4604
4605/* standard posix version of popen() support */
4606static PyObject *
4607posix_popen(PyObject *self, PyObject *args)
4608{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004609 char *name;
4610 char *mode = "r";
4611 int bufsize = -1;
4612 FILE *fp;
4613 PyObject *f;
4614 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4615 return NULL;
4616 Py_BEGIN_ALLOW_THREADS
4617 fp = popen(name, mode);
4618 Py_END_ALLOW_THREADS
4619 if (fp == NULL)
4620 return posix_error();
4621 f = PyFile_FromFile(fp, name, mode, pclose);
4622 if (f != NULL)
4623 PyFile_SetBufSize(f, bufsize);
4624 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004625}
4626
4627/* fork() under OS/2 has lots'o'warts
4628 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4629 * most of this code is a ripoff of the win32 code, but using the
4630 * capabilities of EMX's C library routines
4631 */
4632
4633/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4634#define POPEN_1 1
4635#define POPEN_2 2
4636#define POPEN_3 3
4637#define POPEN_4 4
4638
4639static PyObject *_PyPopen(char *, int, int, int);
4640static int _PyPclose(FILE *file);
4641
4642/*
4643 * Internal dictionary mapping popen* file pointers to process handles,
4644 * for use when retrieving the process exit code. See _PyPclose() below
4645 * for more information on this dictionary's use.
4646 */
4647static PyObject *_PyPopenProcs = NULL;
4648
4649/* os2emx version of popen2()
4650 *
4651 * The result of this function is a pipe (file) connected to the
4652 * process's stdin, and a pipe connected to the process's stdout.
4653 */
4654
4655static PyObject *
4656os2emx_popen2(PyObject *self, PyObject *args)
4657{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004658 PyObject *f;
4659 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004660
Victor Stinnerd6f85422010-05-05 23:33:33 +00004661 char *cmdstring;
4662 char *mode = "t";
4663 int bufsize = -1;
4664 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4665 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004666
Victor Stinnerd6f85422010-05-05 23:33:33 +00004667 if (*mode == 't')
4668 tm = O_TEXT;
4669 else if (*mode != 'b') {
4670 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4671 return NULL;
4672 } else
4673 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004674
Victor Stinnerd6f85422010-05-05 23:33:33 +00004675 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004676
Victor Stinnerd6f85422010-05-05 23:33:33 +00004677 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004678}
4679
4680/*
4681 * Variation on os2emx.popen2
4682 *
4683 * The result of this function is 3 pipes - the process's stdin,
4684 * stdout and stderr
4685 */
4686
4687static PyObject *
4688os2emx_popen3(PyObject *self, PyObject *args)
4689{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004690 PyObject *f;
4691 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004692
Victor Stinnerd6f85422010-05-05 23:33:33 +00004693 char *cmdstring;
4694 char *mode = "t";
4695 int bufsize = -1;
4696 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4697 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004698
Victor Stinnerd6f85422010-05-05 23:33:33 +00004699 if (*mode == 't')
4700 tm = O_TEXT;
4701 else if (*mode != 'b') {
4702 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4703 return NULL;
4704 } else
4705 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004706
Victor Stinnerd6f85422010-05-05 23:33:33 +00004707 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004708
Victor Stinnerd6f85422010-05-05 23:33:33 +00004709 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004710}
4711
4712/*
4713 * Variation on os2emx.popen2
4714 *
Tim Peters11b23062003-04-23 02:39:17 +00004715 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004716 * and stdout+stderr combined as a single pipe.
4717 */
4718
4719static PyObject *
4720os2emx_popen4(PyObject *self, PyObject *args)
4721{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004722 PyObject *f;
4723 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004724
Victor Stinnerd6f85422010-05-05 23:33:33 +00004725 char *cmdstring;
4726 char *mode = "t";
4727 int bufsize = -1;
4728 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4729 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004730
Victor Stinnerd6f85422010-05-05 23:33:33 +00004731 if (*mode == 't')
4732 tm = O_TEXT;
4733 else if (*mode != 'b') {
4734 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4735 return NULL;
4736 } else
4737 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004738
Victor Stinnerd6f85422010-05-05 23:33:33 +00004739 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004740
Victor Stinnerd6f85422010-05-05 23:33:33 +00004741 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004742}
4743
4744/* a couple of structures for convenient handling of multiple
4745 * file handles and pipes
4746 */
4747struct file_ref
4748{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004749 int handle;
4750 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004751};
4752
4753struct pipe_ref
4754{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004755 int rd;
4756 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004757};
4758
4759/* The following code is derived from the win32 code */
4760
4761static PyObject *
4762_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4763{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004764 struct file_ref stdio[3];
4765 struct pipe_ref p_fd[3];
4766 FILE *p_s[3];
4767 int file_count, i, pipe_err;
4768 pid_t pipe_pid;
4769 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4770 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004771
Victor Stinnerd6f85422010-05-05 23:33:33 +00004772 /* file modes for subsequent fdopen's on pipe handles */
4773 if (mode == O_TEXT)
4774 {
4775 rd_mode = "rt";
4776 wr_mode = "wt";
4777 }
4778 else
4779 {
4780 rd_mode = "rb";
4781 wr_mode = "wb";
4782 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004783
Victor Stinnerd6f85422010-05-05 23:33:33 +00004784 /* prepare shell references */
4785 if ((shell = getenv("EMXSHELL")) == NULL)
4786 if ((shell = getenv("COMSPEC")) == NULL)
4787 {
4788 errno = ENOENT;
4789 return posix_error();
4790 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004791
Victor Stinnerd6f85422010-05-05 23:33:33 +00004792 sh_name = _getname(shell);
4793 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4794 opt = "/c";
4795 else
4796 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004797
Victor Stinnerd6f85422010-05-05 23:33:33 +00004798 /* save current stdio fds + their flags, and set not inheritable */
4799 i = pipe_err = 0;
4800 while (pipe_err >= 0 && i < 3)
4801 {
4802 pipe_err = stdio[i].handle = dup(i);
4803 stdio[i].flags = fcntl(i, F_GETFD, 0);
4804 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4805 i++;
4806 }
4807 if (pipe_err < 0)
4808 {
4809 /* didn't get them all saved - clean up and bail out */
4810 int saved_err = errno;
4811 while (i-- > 0)
4812 {
4813 close(stdio[i].handle);
4814 }
4815 errno = saved_err;
4816 return posix_error();
4817 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004818
Victor Stinnerd6f85422010-05-05 23:33:33 +00004819 /* create pipe ends */
4820 file_count = 2;
4821 if (n == POPEN_3)
4822 file_count = 3;
4823 i = pipe_err = 0;
4824 while ((pipe_err == 0) && (i < file_count))
4825 pipe_err = pipe((int *)&p_fd[i++]);
4826 if (pipe_err < 0)
4827 {
4828 /* didn't get them all made - clean up and bail out */
4829 while (i-- > 0)
4830 {
4831 close(p_fd[i].wr);
4832 close(p_fd[i].rd);
4833 }
4834 errno = EPIPE;
4835 return posix_error();
4836 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004837
Victor Stinnerd6f85422010-05-05 23:33:33 +00004838 /* change the actual standard IO streams over temporarily,
4839 * making the retained pipe ends non-inheritable
4840 */
4841 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004842
Victor Stinnerd6f85422010-05-05 23:33:33 +00004843 /* - stdin */
4844 if (dup2(p_fd[0].rd, 0) == 0)
4845 {
4846 close(p_fd[0].rd);
4847 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4848 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4849 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4850 {
4851 close(p_fd[0].wr);
4852 pipe_err = -1;
4853 }
4854 }
4855 else
4856 {
4857 pipe_err = -1;
4858 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004859
Victor Stinnerd6f85422010-05-05 23:33:33 +00004860 /* - stdout */
4861 if (pipe_err == 0)
4862 {
4863 if (dup2(p_fd[1].wr, 1) == 1)
4864 {
4865 close(p_fd[1].wr);
4866 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4867 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4868 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4869 {
4870 close(p_fd[1].rd);
4871 pipe_err = -1;
4872 }
4873 }
4874 else
4875 {
4876 pipe_err = -1;
4877 }
4878 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004879
Victor Stinnerd6f85422010-05-05 23:33:33 +00004880 /* - stderr, as required */
4881 if (pipe_err == 0)
4882 switch (n)
4883 {
4884 case POPEN_3:
4885 {
4886 if (dup2(p_fd[2].wr, 2) == 2)
4887 {
4888 close(p_fd[2].wr);
4889 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4890 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4891 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4892 {
4893 close(p_fd[2].rd);
4894 pipe_err = -1;
4895 }
4896 }
4897 else
4898 {
4899 pipe_err = -1;
4900 }
4901 break;
4902 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004903
Victor Stinnerd6f85422010-05-05 23:33:33 +00004904 case POPEN_4:
4905 {
4906 if (dup2(1, 2) != 2)
4907 {
4908 pipe_err = -1;
4909 }
4910 break;
4911 }
4912 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004913
Victor Stinnerd6f85422010-05-05 23:33:33 +00004914 /* spawn the child process */
4915 if (pipe_err == 0)
4916 {
4917 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4918 if (pipe_pid == -1)
4919 {
4920 pipe_err = -1;
4921 }
4922 else
4923 {
4924 /* save the PID into the FILE structure
4925 * NOTE: this implementation doesn't actually
4926 * take advantage of this, but do it for
4927 * completeness - AIM Apr01
4928 */
4929 for (i = 0; i < file_count; i++)
4930 p_s[i]->_pid = pipe_pid;
4931 }
4932 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004933
Victor Stinnerd6f85422010-05-05 23:33:33 +00004934 /* reset standard IO to normal */
4935 for (i = 0; i < 3; i++)
4936 {
4937 dup2(stdio[i].handle, i);
4938 fcntl(i, F_SETFD, stdio[i].flags);
4939 close(stdio[i].handle);
4940 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004941
Victor Stinnerd6f85422010-05-05 23:33:33 +00004942 /* if any remnant problems, clean up and bail out */
4943 if (pipe_err < 0)
4944 {
4945 for (i = 0; i < 3; i++)
4946 {
4947 close(p_fd[i].rd);
4948 close(p_fd[i].wr);
4949 }
4950 errno = EPIPE;
4951 return posix_error_with_filename(cmdstring);
4952 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004953
Victor Stinnerd6f85422010-05-05 23:33:33 +00004954 /* build tuple of file objects to return */
4955 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4956 PyFile_SetBufSize(p_f[0], bufsize);
4957 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4958 PyFile_SetBufSize(p_f[1], bufsize);
4959 if (n == POPEN_3)
4960 {
4961 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4962 PyFile_SetBufSize(p_f[0], bufsize);
4963 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4964 }
4965 else
4966 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004967
Victor Stinnerd6f85422010-05-05 23:33:33 +00004968 /*
4969 * Insert the files we've created into the process dictionary
4970 * all referencing the list with the process handle and the
4971 * initial number of files (see description below in _PyPclose).
4972 * Since if _PyPclose later tried to wait on a process when all
4973 * handles weren't closed, it could create a deadlock with the
4974 * child, we spend some energy here to try to ensure that we
4975 * either insert all file handles into the dictionary or none
4976 * at all. It's a little clumsy with the various popen modes
4977 * and variable number of files involved.
4978 */
4979 if (!_PyPopenProcs)
4980 {
4981 _PyPopenProcs = PyDict_New();
4982 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004983
Victor Stinnerd6f85422010-05-05 23:33:33 +00004984 if (_PyPopenProcs)
4985 {
4986 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4987 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004988
Victor Stinnerd6f85422010-05-05 23:33:33 +00004989 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4990 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004991
Victor Stinnerd6f85422010-05-05 23:33:33 +00004992 procObj = PyList_New(2);
4993 pidObj = PyLong_FromPid(pipe_pid);
4994 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004995
Victor Stinnerd6f85422010-05-05 23:33:33 +00004996 if (procObj && pidObj && intObj)
4997 {
4998 PyList_SetItem(procObj, 0, pidObj);
4999 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005000
Victor Stinnerd6f85422010-05-05 23:33:33 +00005001 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
5002 if (fileObj[0])
5003 {
5004 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5005 fileObj[0],
5006 procObj);
5007 }
5008 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5009 if (fileObj[1])
5010 {
5011 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5012 fileObj[1],
5013 procObj);
5014 }
5015 if (file_count >= 3)
5016 {
5017 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5018 if (fileObj[2])
5019 {
5020 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5021 fileObj[2],
5022 procObj);
5023 }
5024 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005025
Victor Stinnerd6f85422010-05-05 23:33:33 +00005026 if (ins_rc[0] < 0 || !fileObj[0] ||
5027 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5028 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5029 {
5030 /* Something failed - remove any dictionary
5031 * entries that did make it.
5032 */
5033 if (!ins_rc[0] && fileObj[0])
5034 {
5035 PyDict_DelItem(_PyPopenProcs,
5036 fileObj[0]);
5037 }
5038 if (!ins_rc[1] && fileObj[1])
5039 {
5040 PyDict_DelItem(_PyPopenProcs,
5041 fileObj[1]);
5042 }
5043 if (!ins_rc[2] && fileObj[2])
5044 {
5045 PyDict_DelItem(_PyPopenProcs,
5046 fileObj[2]);
5047 }
5048 }
5049 }
Tim Peters11b23062003-04-23 02:39:17 +00005050
Victor Stinnerd6f85422010-05-05 23:33:33 +00005051 /*
5052 * Clean up our localized references for the dictionary keys
5053 * and value since PyDict_SetItem will Py_INCREF any copies
5054 * that got placed in the dictionary.
5055 */
5056 Py_XDECREF(procObj);
5057 Py_XDECREF(fileObj[0]);
5058 Py_XDECREF(fileObj[1]);
5059 Py_XDECREF(fileObj[2]);
5060 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005061
Victor Stinnerd6f85422010-05-05 23:33:33 +00005062 /* Child is launched. */
5063 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005064}
5065
5066/*
5067 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5068 * exit code for the child process and return as a result of the close.
5069 *
5070 * This function uses the _PyPopenProcs dictionary in order to map the
5071 * input file pointer to information about the process that was
5072 * originally created by the popen* call that created the file pointer.
5073 * The dictionary uses the file pointer as a key (with one entry
5074 * inserted for each file returned by the original popen* call) and a
5075 * single list object as the value for all files from a single call.
5076 * The list object contains the Win32 process handle at [0], and a file
5077 * count at [1], which is initialized to the total number of file
5078 * handles using that list.
5079 *
5080 * This function closes whichever handle it is passed, and decrements
5081 * the file count in the dictionary for the process handle pointed to
5082 * by this file. On the last close (when the file count reaches zero),
5083 * this function will wait for the child process and then return its
5084 * exit code as the result of the close() operation. This permits the
5085 * files to be closed in any order - it is always the close() of the
5086 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005087 *
5088 * NOTE: This function is currently called with the GIL released.
5089 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005090 */
5091
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005092static int _PyPclose(FILE *file)
5093{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005094 int result;
5095 int exit_code;
5096 pid_t pipe_pid;
5097 PyObject *procObj, *pidObj, *intObj, *fileObj;
5098 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005099#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005100 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005101#endif
5102
Victor Stinnerd6f85422010-05-05 23:33:33 +00005103 /* Close the file handle first, to ensure it can't block the
5104 * child from exiting if it's the last handle.
5105 */
5106 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005107
5108#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005109 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005110#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005111 if (_PyPopenProcs)
5112 {
5113 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5114 (procObj = PyDict_GetItem(_PyPopenProcs,
5115 fileObj)) != NULL &&
5116 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5117 (intObj = PyList_GetItem(procObj,1)) != NULL)
5118 {
5119 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5120 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005121
Victor Stinnerd6f85422010-05-05 23:33:33 +00005122 if (file_count > 1)
5123 {
5124 /* Still other files referencing process */
5125 file_count--;
5126 PyList_SetItem(procObj,1,
5127 PyInt_FromLong((long) file_count));
5128 }
5129 else
5130 {
5131 /* Last file for this process */
5132 if (result != EOF &&
5133 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5134 {
5135 /* extract exit status */
5136 if (WIFEXITED(exit_code))
5137 {
5138 result = WEXITSTATUS(exit_code);
5139 }
5140 else
5141 {
5142 errno = EPIPE;
5143 result = -1;
5144 }
5145 }
5146 else
5147 {
5148 /* Indicate failure - this will cause the file object
5149 * to raise an I/O error and translate the last
5150 * error code from errno. We do have a problem with
5151 * last errors that overlap the normal errno table,
5152 * but that's a consistent problem with the file object.
5153 */
5154 result = -1;
5155 }
5156 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005157
Victor Stinnerd6f85422010-05-05 23:33:33 +00005158 /* Remove this file pointer from dictionary */
5159 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005160
Victor Stinnerd6f85422010-05-05 23:33:33 +00005161 if (PyDict_Size(_PyPopenProcs) == 0)
5162 {
5163 Py_DECREF(_PyPopenProcs);
5164 _PyPopenProcs = NULL;
5165 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005166
Victor Stinnerd6f85422010-05-05 23:33:33 +00005167 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005168
Victor Stinnerd6f85422010-05-05 23:33:33 +00005169 Py_XDECREF(fileObj);
5170 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005171
5172#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005173 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005174#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005175 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005176}
5177
5178#endif /* PYCC_??? */
5179
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005180#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005181
5182/*
5183 * Portable 'popen' replacement for Win32.
5184 *
5185 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5186 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005187 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005188 */
5189
5190#include <malloc.h>
5191#include <io.h>
5192#include <fcntl.h>
5193
5194/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5195#define POPEN_1 1
5196#define POPEN_2 2
5197#define POPEN_3 3
5198#define POPEN_4 4
5199
5200static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005201static int _PyPclose(FILE *file);
5202
5203/*
5204 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005205 * for use when retrieving the process exit code. See _PyPclose() below
5206 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005207 */
5208static PyObject *_PyPopenProcs = NULL;
5209
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005210
5211/* popen that works from a GUI.
5212 *
5213 * The result of this function is a pipe (file) connected to the
5214 * processes stdin or stdout, depending on the requested mode.
5215 */
5216
5217static PyObject *
5218posix_popen(PyObject *self, PyObject *args)
5219{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005220 PyObject *f;
5221 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005222
Victor Stinnerd6f85422010-05-05 23:33:33 +00005223 char *cmdstring;
5224 char *mode = "r";
5225 int bufsize = -1;
5226 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5227 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005228
Victor Stinnerd6f85422010-05-05 23:33:33 +00005229 if (*mode == 'r')
5230 tm = _O_RDONLY;
5231 else if (*mode != 'w') {
5232 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5233 return NULL;
5234 } else
5235 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005236
Victor Stinnerd6f85422010-05-05 23:33:33 +00005237 if (bufsize != -1) {
5238 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5239 return NULL;
5240 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005241
Victor Stinnerd6f85422010-05-05 23:33:33 +00005242 if (*(mode+1) == 't')
5243 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5244 else if (*(mode+1) == 'b')
5245 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5246 else
5247 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005248
Victor Stinnerd6f85422010-05-05 23:33:33 +00005249 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005250}
5251
5252/* Variation on win32pipe.popen
5253 *
5254 * The result of this function is a pipe (file) connected to the
5255 * process's stdin, and a pipe connected to the process's stdout.
5256 */
5257
5258static PyObject *
5259win32_popen2(PyObject *self, PyObject *args)
5260{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005261 PyObject *f;
5262 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Victor Stinnerd6f85422010-05-05 23:33:33 +00005264 char *cmdstring;
5265 char *mode = "t";
5266 int bufsize = -1;
5267 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5268 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005269
Victor Stinnerd6f85422010-05-05 23:33:33 +00005270 if (*mode == 't')
5271 tm = _O_TEXT;
5272 else if (*mode != 'b') {
5273 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5274 return NULL;
5275 } else
5276 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005277
Victor Stinnerd6f85422010-05-05 23:33:33 +00005278 if (bufsize != -1) {
5279 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5280 return NULL;
5281 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005282
Victor Stinnerd6f85422010-05-05 23:33:33 +00005283 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005284
Victor Stinnerd6f85422010-05-05 23:33:33 +00005285 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005286}
5287
5288/*
5289 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005290 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005291 * The result of this function is 3 pipes - the process's stdin,
5292 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005293 */
5294
5295static PyObject *
5296win32_popen3(PyObject *self, PyObject *args)
5297{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005298 PyObject *f;
5299 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005300
Victor Stinnerd6f85422010-05-05 23:33:33 +00005301 char *cmdstring;
5302 char *mode = "t";
5303 int bufsize = -1;
5304 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5305 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005306
Victor Stinnerd6f85422010-05-05 23:33:33 +00005307 if (*mode == 't')
5308 tm = _O_TEXT;
5309 else if (*mode != 'b') {
5310 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5311 return NULL;
5312 } else
5313 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005314
Victor Stinnerd6f85422010-05-05 23:33:33 +00005315 if (bufsize != -1) {
5316 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5317 return NULL;
5318 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005319
Victor Stinnerd6f85422010-05-05 23:33:33 +00005320 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005321
Victor Stinnerd6f85422010-05-05 23:33:33 +00005322 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005323}
5324
5325/*
5326 * Variation on win32pipe.popen
5327 *
Tim Peters5aa91602002-01-30 05:46:57 +00005328 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005329 * and stdout+stderr combined as a single pipe.
5330 */
5331
5332static PyObject *
5333win32_popen4(PyObject *self, PyObject *args)
5334{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005335 PyObject *f;
5336 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005337
Victor Stinnerd6f85422010-05-05 23:33:33 +00005338 char *cmdstring;
5339 char *mode = "t";
5340 int bufsize = -1;
5341 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5342 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005343
Victor Stinnerd6f85422010-05-05 23:33:33 +00005344 if (*mode == 't')
5345 tm = _O_TEXT;
5346 else if (*mode != 'b') {
5347 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5348 return NULL;
5349 } else
5350 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005351
Victor Stinnerd6f85422010-05-05 23:33:33 +00005352 if (bufsize != -1) {
5353 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5354 return NULL;
5355 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005356
Victor Stinnerd6f85422010-05-05 23:33:33 +00005357 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005358
Victor Stinnerd6f85422010-05-05 23:33:33 +00005359 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005360}
5361
Mark Hammond08501372001-01-31 07:30:29 +00005362static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005363_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005364 HANDLE hStdin,
5365 HANDLE hStdout,
5366 HANDLE hStderr,
5367 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005368{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005369 PROCESS_INFORMATION piProcInfo;
5370 STARTUPINFO siStartInfo;
5371 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5372 char *s1,*s2, *s3 = " /c ";
5373 const char *szConsoleSpawn = "w9xpopen.exe";
5374 int i;
5375 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005376
Victor Stinnerd6f85422010-05-05 23:33:33 +00005377 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5378 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005379
Victor Stinnerd6f85422010-05-05 23:33:33 +00005380 s1 = (char *)alloca(i);
5381 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5382 /* x < i, so x fits into an integer */
5383 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005384
Victor Stinnerd6f85422010-05-05 23:33:33 +00005385 /* Explicitly check if we are using COMMAND.COM. If we are
5386 * then use the w9xpopen hack.
5387 */
5388 comshell = s1 + x;
5389 while (comshell >= s1 && *comshell != '\\')
5390 --comshell;
5391 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005392
Victor Stinnerd6f85422010-05-05 23:33:33 +00005393 if (GetVersion() < 0x80000000 &&
5394 _stricmp(comshell, "command.com") != 0) {
5395 /* NT/2000 and not using command.com. */
5396 x = i + strlen(s3) + strlen(cmdstring) + 1;
5397 s2 = (char *)alloca(x);
5398 ZeroMemory(s2, x);
5399 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5400 }
5401 else {
5402 /*
5403 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5404 * the workaround listed in KB: Q150956
5405 */
5406 char modulepath[_MAX_PATH];
5407 struct stat statinfo;
5408 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5409 for (x = i = 0; modulepath[i]; i++)
5410 if (modulepath[i] == SEP)
5411 x = i+1;
5412 modulepath[x] = '\0';
5413 /* Create the full-name to w9xpopen, so we can test it exists */
5414 strncat(modulepath,
5415 szConsoleSpawn,
5416 (sizeof(modulepath)/sizeof(modulepath[0]))
5417 -strlen(modulepath));
5418 if (stat(modulepath, &statinfo) != 0) {
5419 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5420 /* Eeek - file-not-found - possibly an embedding
5421 situation - see if we can locate it in sys.prefix
5422 */
5423 strncpy(modulepath,
5424 Py_GetExecPrefix(),
5425 mplen);
5426 modulepath[mplen-1] = '\0';
5427 if (modulepath[strlen(modulepath)-1] != '\\')
5428 strcat(modulepath, "\\");
5429 strncat(modulepath,
5430 szConsoleSpawn,
5431 mplen-strlen(modulepath));
5432 /* No where else to look - raise an easily identifiable
5433 error, rather than leaving Windows to report
5434 "file not found" - as the user is probably blissfully
5435 unaware this shim EXE is used, and it will confuse them.
5436 (well, it confused me for a while ;-)
5437 */
5438 if (stat(modulepath, &statinfo) != 0) {
5439 PyErr_Format(PyExc_RuntimeError,
5440 "Can not locate '%s' which is needed "
5441 "for popen to work with your shell "
5442 "or platform.",
5443 szConsoleSpawn);
5444 return FALSE;
5445 }
5446 }
5447 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5448 strlen(modulepath) +
5449 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005450
Victor Stinnerd6f85422010-05-05 23:33:33 +00005451 s2 = (char *)alloca(x);
5452 ZeroMemory(s2, x);
5453 /* To maintain correct argument passing semantics,
5454 we pass the command-line as it stands, and allow
5455 quoting to be applied. w9xpopen.exe will then
5456 use its argv vector, and re-quote the necessary
5457 args for the ultimate child process.
5458 */
5459 PyOS_snprintf(
5460 s2, x,
5461 "\"%s\" %s%s%s",
5462 modulepath,
5463 s1,
5464 s3,
5465 cmdstring);
5466 /* Not passing CREATE_NEW_CONSOLE has been known to
5467 cause random failures on win9x. Specifically a
5468 dialog:
5469 "Your program accessed mem currently in use at xxx"
5470 and a hopeful warning about the stability of your
5471 system.
5472 Cost is Ctrl+C won't kill children, but anyone
5473 who cares can have a go!
5474 */
5475 dwProcessFlags |= CREATE_NEW_CONSOLE;
5476 }
5477 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005478
Victor Stinnerd6f85422010-05-05 23:33:33 +00005479 /* Could be an else here to try cmd.exe / command.com in the path
5480 Now we'll just error out.. */
5481 else {
5482 PyErr_SetString(PyExc_RuntimeError,
5483 "Cannot locate a COMSPEC environment variable to "
5484 "use as the shell");
5485 return FALSE;
5486 }
Tim Peters5aa91602002-01-30 05:46:57 +00005487
Victor Stinnerd6f85422010-05-05 23:33:33 +00005488 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5489 siStartInfo.cb = sizeof(STARTUPINFO);
5490 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5491 siStartInfo.hStdInput = hStdin;
5492 siStartInfo.hStdOutput = hStdout;
5493 siStartInfo.hStdError = hStderr;
5494 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005495
Victor Stinnerd6f85422010-05-05 23:33:33 +00005496 if (CreateProcess(NULL,
5497 s2,
5498 NULL,
5499 NULL,
5500 TRUE,
5501 dwProcessFlags,
5502 NULL,
5503 NULL,
5504 &siStartInfo,
5505 &piProcInfo) ) {
5506 /* Close the handles now so anyone waiting is woken. */
5507 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005508
Victor Stinnerd6f85422010-05-05 23:33:33 +00005509 /* Return process handle */
5510 *hProcess = piProcInfo.hProcess;
5511 return TRUE;
5512 }
5513 win32_error("CreateProcess", s2);
5514 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005515}
5516
5517/* The following code is based off of KB: Q190351 */
5518
5519static PyObject *
5520_PyPopen(char *cmdstring, int mode, int n)
5521{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005522 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5523 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5524 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005525
Victor Stinnerd6f85422010-05-05 23:33:33 +00005526 SECURITY_ATTRIBUTES saAttr;
5527 BOOL fSuccess;
5528 int fd1, fd2, fd3;
5529 FILE *f1, *f2, *f3;
5530 long file_count;
5531 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005532
Victor Stinnerd6f85422010-05-05 23:33:33 +00005533 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5534 saAttr.bInheritHandle = TRUE;
5535 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005536
Victor Stinnerd6f85422010-05-05 23:33:33 +00005537 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5538 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005539
Victor Stinnerd6f85422010-05-05 23:33:33 +00005540 /* Create new output read handle and the input write handle. Set
5541 * the inheritance properties to FALSE. Otherwise, the child inherits
5542 * these handles; resulting in non-closeable handles to the pipes
5543 * being created. */
5544 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5545 GetCurrentProcess(), &hChildStdinWrDup, 0,
5546 FALSE,
5547 DUPLICATE_SAME_ACCESS);
5548 if (!fSuccess)
5549 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005550
Victor Stinnerd6f85422010-05-05 23:33:33 +00005551 /* Close the inheritable version of ChildStdin
5552 that we're using. */
5553 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005554
Victor Stinnerd6f85422010-05-05 23:33:33 +00005555 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5556 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005557
Victor Stinnerd6f85422010-05-05 23:33:33 +00005558 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5559 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5560 FALSE, DUPLICATE_SAME_ACCESS);
5561 if (!fSuccess)
5562 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005563
Victor Stinnerd6f85422010-05-05 23:33:33 +00005564 /* Close the inheritable version of ChildStdout
5565 that we're using. */
5566 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005567
Victor Stinnerd6f85422010-05-05 23:33:33 +00005568 if (n != POPEN_4) {
5569 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5570 return win32_error("CreatePipe", NULL);
5571 fSuccess = DuplicateHandle(GetCurrentProcess(),
5572 hChildStderrRd,
5573 GetCurrentProcess(),
5574 &hChildStderrRdDup, 0,
5575 FALSE, DUPLICATE_SAME_ACCESS);
5576 if (!fSuccess)
5577 return win32_error("DuplicateHandle", NULL);
5578 /* Close the inheritable version of ChildStdErr that we're using. */
5579 CloseHandle(hChildStderrRd);
5580 }
Tim Peters5aa91602002-01-30 05:46:57 +00005581
Victor Stinnerd6f85422010-05-05 23:33:33 +00005582 switch (n) {
5583 case POPEN_1:
5584 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5585 case _O_WRONLY | _O_TEXT:
5586 /* Case for writing to child Stdin in text mode. */
5587 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5588 f1 = _fdopen(fd1, "w");
5589 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5590 PyFile_SetBufSize(f, 0);
5591 /* We don't care about these pipes anymore, so close them. */
5592 CloseHandle(hChildStdoutRdDup);
5593 CloseHandle(hChildStderrRdDup);
5594 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005595
Victor Stinnerd6f85422010-05-05 23:33:33 +00005596 case _O_RDONLY | _O_TEXT:
5597 /* Case for reading from child Stdout in text mode. */
5598 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5599 f1 = _fdopen(fd1, "r");
5600 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5601 PyFile_SetBufSize(f, 0);
5602 /* We don't care about these pipes anymore, so close them. */
5603 CloseHandle(hChildStdinWrDup);
5604 CloseHandle(hChildStderrRdDup);
5605 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005606
Victor Stinnerd6f85422010-05-05 23:33:33 +00005607 case _O_RDONLY | _O_BINARY:
5608 /* Case for readinig from child Stdout in binary mode. */
5609 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5610 f1 = _fdopen(fd1, "rb");
5611 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5612 PyFile_SetBufSize(f, 0);
5613 /* We don't care about these pipes anymore, so close them. */
5614 CloseHandle(hChildStdinWrDup);
5615 CloseHandle(hChildStderrRdDup);
5616 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005617
Victor Stinnerd6f85422010-05-05 23:33:33 +00005618 case _O_WRONLY | _O_BINARY:
5619 /* Case for writing to child Stdin in binary mode. */
5620 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5621 f1 = _fdopen(fd1, "wb");
5622 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5623 PyFile_SetBufSize(f, 0);
5624 /* We don't care about these pipes anymore, so close them. */
5625 CloseHandle(hChildStdoutRdDup);
5626 CloseHandle(hChildStderrRdDup);
5627 break;
5628 }
5629 file_count = 1;
5630 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005631
Victor Stinnerd6f85422010-05-05 23:33:33 +00005632 case POPEN_2:
5633 case POPEN_4:
5634 {
5635 char *m1, *m2;
5636 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005637
Victor Stinnerd6f85422010-05-05 23:33:33 +00005638 if (mode & _O_TEXT) {
5639 m1 = "r";
5640 m2 = "w";
5641 } else {
5642 m1 = "rb";
5643 m2 = "wb";
5644 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005645
Victor Stinnerd6f85422010-05-05 23:33:33 +00005646 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5647 f1 = _fdopen(fd1, m2);
5648 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5649 f2 = _fdopen(fd2, m1);
5650 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5651 PyFile_SetBufSize(p1, 0);
5652 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5653 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005654
Victor Stinnerd6f85422010-05-05 23:33:33 +00005655 if (n != 4)
5656 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005657
Victor Stinnerd6f85422010-05-05 23:33:33 +00005658 f = PyTuple_Pack(2,p1,p2);
5659 Py_XDECREF(p1);
5660 Py_XDECREF(p2);
5661 file_count = 2;
5662 break;
5663 }
Tim Peters5aa91602002-01-30 05:46:57 +00005664
Victor Stinnerd6f85422010-05-05 23:33:33 +00005665 case POPEN_3:
5666 {
5667 char *m1, *m2;
5668 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005669
Victor Stinnerd6f85422010-05-05 23:33:33 +00005670 if (mode & _O_TEXT) {
5671 m1 = "r";
5672 m2 = "w";
5673 } else {
5674 m1 = "rb";
5675 m2 = "wb";
5676 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005677
Victor Stinnerd6f85422010-05-05 23:33:33 +00005678 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5679 f1 = _fdopen(fd1, m2);
5680 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5681 f2 = _fdopen(fd2, m1);
5682 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5683 f3 = _fdopen(fd3, m1);
5684 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5685 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5686 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5687 PyFile_SetBufSize(p1, 0);
5688 PyFile_SetBufSize(p2, 0);
5689 PyFile_SetBufSize(p3, 0);
5690 f = PyTuple_Pack(3,p1,p2,p3);
5691 Py_XDECREF(p1);
5692 Py_XDECREF(p2);
5693 Py_XDECREF(p3);
5694 file_count = 3;
5695 break;
5696 }
5697 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005698
Victor Stinnerd6f85422010-05-05 23:33:33 +00005699 if (n == POPEN_4) {
5700 if (!_PyPopenCreateProcess(cmdstring,
5701 hChildStdinRd,
5702 hChildStdoutWr,
5703 hChildStdoutWr,
5704 &hProcess))
5705 return NULL;
5706 }
5707 else {
5708 if (!_PyPopenCreateProcess(cmdstring,
5709 hChildStdinRd,
5710 hChildStdoutWr,
5711 hChildStderrWr,
5712 &hProcess))
5713 return NULL;
5714 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005715
Victor Stinnerd6f85422010-05-05 23:33:33 +00005716 /*
5717 * Insert the files we've created into the process dictionary
5718 * all referencing the list with the process handle and the
5719 * initial number of files (see description below in _PyPclose).
5720 * Since if _PyPclose later tried to wait on a process when all
5721 * handles weren't closed, it could create a deadlock with the
5722 * child, we spend some energy here to try to ensure that we
5723 * either insert all file handles into the dictionary or none
5724 * at all. It's a little clumsy with the various popen modes
5725 * and variable number of files involved.
5726 */
5727 if (!_PyPopenProcs) {
5728 _PyPopenProcs = PyDict_New();
5729 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005730
Victor Stinnerd6f85422010-05-05 23:33:33 +00005731 if (_PyPopenProcs) {
5732 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5733 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005734
Victor Stinnerd6f85422010-05-05 23:33:33 +00005735 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5736 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005737
Victor Stinnerd6f85422010-05-05 23:33:33 +00005738 procObj = PyList_New(2);
5739 hProcessObj = PyLong_FromVoidPtr(hProcess);
5740 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005741
Victor Stinnerd6f85422010-05-05 23:33:33 +00005742 if (procObj && hProcessObj && intObj) {
5743 PyList_SetItem(procObj,0,hProcessObj);
5744 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005745
Victor Stinnerd6f85422010-05-05 23:33:33 +00005746 fileObj[0] = PyLong_FromVoidPtr(f1);
5747 if (fileObj[0]) {
5748 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5749 fileObj[0],
5750 procObj);
5751 }
5752 if (file_count >= 2) {
5753 fileObj[1] = PyLong_FromVoidPtr(f2);
5754 if (fileObj[1]) {
5755 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5756 fileObj[1],
5757 procObj);
5758 }
5759 }
5760 if (file_count >= 3) {
5761 fileObj[2] = PyLong_FromVoidPtr(f3);
5762 if (fileObj[2]) {
5763 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5764 fileObj[2],
5765 procObj);
5766 }
5767 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005768
Victor Stinnerd6f85422010-05-05 23:33:33 +00005769 if (ins_rc[0] < 0 || !fileObj[0] ||
5770 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5771 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5772 /* Something failed - remove any dictionary
5773 * entries that did make it.
5774 */
5775 if (!ins_rc[0] && fileObj[0]) {
5776 PyDict_DelItem(_PyPopenProcs,
5777 fileObj[0]);
5778 }
5779 if (!ins_rc[1] && fileObj[1]) {
5780 PyDict_DelItem(_PyPopenProcs,
5781 fileObj[1]);
5782 }
5783 if (!ins_rc[2] && fileObj[2]) {
5784 PyDict_DelItem(_PyPopenProcs,
5785 fileObj[2]);
5786 }
5787 }
5788 }
Tim Peters5aa91602002-01-30 05:46:57 +00005789
Victor Stinnerd6f85422010-05-05 23:33:33 +00005790 /*
5791 * Clean up our localized references for the dictionary keys
5792 * and value since PyDict_SetItem will Py_INCREF any copies
5793 * that got placed in the dictionary.
5794 */
5795 Py_XDECREF(procObj);
5796 Py_XDECREF(fileObj[0]);
5797 Py_XDECREF(fileObj[1]);
5798 Py_XDECREF(fileObj[2]);
5799 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005800
Victor Stinnerd6f85422010-05-05 23:33:33 +00005801 /* Child is launched. Close the parents copy of those pipe
5802 * handles that only the child should have open. You need to
5803 * make sure that no handles to the write end of the output pipe
5804 * are maintained in this process or else the pipe will not close
5805 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005806
Victor Stinnerd6f85422010-05-05 23:33:33 +00005807 if (!CloseHandle(hChildStdinRd))
5808 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005809
Victor Stinnerd6f85422010-05-05 23:33:33 +00005810 if (!CloseHandle(hChildStdoutWr))
5811 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005812
Victor Stinnerd6f85422010-05-05 23:33:33 +00005813 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5814 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005815
Victor Stinnerd6f85422010-05-05 23:33:33 +00005816 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005817}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005818
5819/*
5820 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5821 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005822 *
5823 * This function uses the _PyPopenProcs dictionary in order to map the
5824 * input file pointer to information about the process that was
5825 * originally created by the popen* call that created the file pointer.
5826 * The dictionary uses the file pointer as a key (with one entry
5827 * inserted for each file returned by the original popen* call) and a
5828 * single list object as the value for all files from a single call.
5829 * The list object contains the Win32 process handle at [0], and a file
5830 * count at [1], which is initialized to the total number of file
5831 * handles using that list.
5832 *
5833 * This function closes whichever handle it is passed, and decrements
5834 * the file count in the dictionary for the process handle pointed to
5835 * by this file. On the last close (when the file count reaches zero),
5836 * this function will wait for the child process and then return its
5837 * exit code as the result of the close() operation. This permits the
5838 * files to be closed in any order - it is always the close() of the
5839 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005840 *
5841 * NOTE: This function is currently called with the GIL released.
5842 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005843 */
Tim Peters736aa322000-09-01 06:51:24 +00005844
Fredrik Lundh56055a42000-07-23 19:47:12 +00005845static int _PyPclose(FILE *file)
5846{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005847 int result;
5848 DWORD exit_code;
5849 HANDLE hProcess;
5850 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5851 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005852#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005853 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005854#endif
5855
Victor Stinnerd6f85422010-05-05 23:33:33 +00005856 /* Close the file handle first, to ensure it can't block the
5857 * child from exiting if it's the last handle.
5858 */
5859 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005860#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005861 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005862#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005863 if (_PyPopenProcs) {
5864 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5865 (procObj = PyDict_GetItem(_PyPopenProcs,
5866 fileObj)) != NULL &&
5867 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5868 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005869
Victor Stinnerd6f85422010-05-05 23:33:33 +00005870 hProcess = PyLong_AsVoidPtr(hProcessObj);
5871 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005872
Victor Stinnerd6f85422010-05-05 23:33:33 +00005873 if (file_count > 1) {
5874 /* Still other files referencing process */
5875 file_count--;
5876 PyList_SetItem(procObj,1,
5877 PyInt_FromLong(file_count));
5878 } else {
5879 /* Last file for this process */
5880 if (result != EOF &&
5881 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5882 GetExitCodeProcess(hProcess, &exit_code)) {
5883 /* Possible truncation here in 16-bit environments, but
5884 * real exit codes are just the lower byte in any event.
5885 */
5886 result = exit_code;
5887 } else {
5888 /* Indicate failure - this will cause the file object
5889 * to raise an I/O error and translate the last Win32
5890 * error code from errno. We do have a problem with
5891 * last errors that overlap the normal errno table,
5892 * but that's a consistent problem with the file object.
5893 */
5894 if (result != EOF) {
5895 /* If the error wasn't from the fclose(), then
5896 * set errno for the file object error handling.
5897 */
5898 errno = GetLastError();
5899 }
5900 result = -1;
5901 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005902
Victor Stinnerd6f85422010-05-05 23:33:33 +00005903 /* Free up the native handle at this point */
5904 CloseHandle(hProcess);
5905 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005906
Victor Stinnerd6f85422010-05-05 23:33:33 +00005907 /* Remove this file pointer from dictionary */
5908 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005909
Victor Stinnerd6f85422010-05-05 23:33:33 +00005910 if (PyDict_Size(_PyPopenProcs) == 0) {
5911 Py_DECREF(_PyPopenProcs);
5912 _PyPopenProcs = NULL;
5913 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005914
Victor Stinnerd6f85422010-05-05 23:33:33 +00005915 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005916
Victor Stinnerd6f85422010-05-05 23:33:33 +00005917 Py_XDECREF(fileObj);
5918 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005919
Tim Peters736aa322000-09-01 06:51:24 +00005920#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005921 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005922#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005923 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005924}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005925
5926#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005928posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005929{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005930 char *name;
5931 char *mode = "r";
5932 int bufsize = -1;
5933 FILE *fp;
5934 PyObject *f;
5935 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5936 return NULL;
5937 /* Strip mode of binary or text modifiers */
5938 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5939 mode = "r";
5940 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5941 mode = "w";
5942 Py_BEGIN_ALLOW_THREADS
5943 fp = popen(name, mode);
5944 Py_END_ALLOW_THREADS
5945 if (fp == NULL)
5946 return posix_error();
5947 f = PyFile_FromFile(fp, name, mode, pclose);
5948 if (f != NULL)
5949 PyFile_SetBufSize(f, bufsize);
5950 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005951}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005952
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005953#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005954#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005956
Guido van Rossumb6775db1994-08-01 11:34:53 +00005957#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005958PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005959"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005960Set the current process's user id.");
5961
Barry Warsaw53699e91996-12-10 23:23:01 +00005962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005963posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005964{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005965 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005966 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005967 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005968 if (setuid(uid) < 0)
5969 return posix_error();
5970 Py_INCREF(Py_None);
5971 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005972}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005973#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005974
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005975
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005976#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005978"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979Set the current process's effective user id.");
5980
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005981static PyObject *
5982posix_seteuid (PyObject *self, PyObject *args)
5983{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005984 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005985 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005986 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005987 if (seteuid(euid) < 0) {
5988 return posix_error();
5989 } else {
5990 Py_INCREF(Py_None);
5991 return Py_None;
5992 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005993}
5994#endif /* HAVE_SETEUID */
5995
5996#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005997PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005998"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999Set the current process's effective group id.");
6000
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006001static PyObject *
6002posix_setegid (PyObject *self, PyObject *args)
6003{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006004 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006005 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006006 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006007 if (setegid(egid) < 0) {
6008 return posix_error();
6009 } else {
6010 Py_INCREF(Py_None);
6011 return Py_None;
6012 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006013}
6014#endif /* HAVE_SETEGID */
6015
6016#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006017PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006018"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006019Set the current process's real and effective user ids.");
6020
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006021static PyObject *
6022posix_setreuid (PyObject *self, PyObject *args)
6023{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006024 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006025 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6026 _Py_Uid_Converter, &ruid,
6027 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006028 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006029 if (setreuid(ruid, euid) < 0) {
6030 return posix_error();
6031 } else {
6032 Py_INCREF(Py_None);
6033 return Py_None;
6034 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006035}
6036#endif /* HAVE_SETREUID */
6037
6038#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006040"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006041Set the current process's real and effective group ids.");
6042
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006043static PyObject *
6044posix_setregid (PyObject *self, PyObject *args)
6045{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006046 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006047 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6048 _Py_Gid_Converter, &rgid,
6049 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006050 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006051 if (setregid(rgid, egid) < 0) {
6052 return posix_error();
6053 } else {
6054 Py_INCREF(Py_None);
6055 return Py_None;
6056 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006057}
6058#endif /* HAVE_SETREGID */
6059
Guido van Rossumb6775db1994-08-01 11:34:53 +00006060#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006062"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006064
Barry Warsaw53699e91996-12-10 23:23:01 +00006065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006066posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006067{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006068 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006069 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006070 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006071 if (setgid(gid) < 0)
6072 return posix_error();
6073 Py_INCREF(Py_None);
6074 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006075}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006076#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006077
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006078#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006082
6083static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006084posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006085{
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006086 Py_ssize_t i, len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006087 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006088
Victor Stinnerd6f85422010-05-05 23:33:33 +00006089 if (!PySequence_Check(groups)) {
6090 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6091 return NULL;
6092 }
6093 len = PySequence_Size(groups);
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006094 if (len < 0) {
6095 return NULL;
6096 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006097 if (len > MAX_GROUPS) {
6098 PyErr_SetString(PyExc_ValueError, "too many groups");
6099 return NULL;
6100 }
6101 for(i = 0; i < len; i++) {
6102 PyObject *elem;
6103 elem = PySequence_GetItem(groups, i);
6104 if (!elem)
6105 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006106 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6107 PyErr_SetString(PyExc_TypeError,
6108 "groups must be integers");
6109 Py_DECREF(elem);
6110 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006111 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006112 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006113 Py_DECREF(elem);
6114 return NULL;
6115 }
6116 }
6117 Py_DECREF(elem);
6118 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006119
Victor Stinnerd6f85422010-05-05 23:33:33 +00006120 if (setgroups(len, grouplist) < 0)
6121 return posix_error();
6122 Py_INCREF(Py_None);
6123 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006124}
6125#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006127#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006128static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006129wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006130{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006131 PyObject *result;
6132 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006133
Victor Stinnerd6f85422010-05-05 23:33:33 +00006134 if (pid == -1)
6135 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006136
Victor Stinnerd6f85422010-05-05 23:33:33 +00006137 if (struct_rusage == NULL) {
6138 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6139 if (m == NULL)
6140 return NULL;
6141 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6142 Py_DECREF(m);
6143 if (struct_rusage == NULL)
6144 return NULL;
6145 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006146
Victor Stinnerd6f85422010-05-05 23:33:33 +00006147 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6148 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6149 if (!result)
6150 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006151
6152#ifndef doubletime
6153#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6154#endif
6155
Victor Stinnerd6f85422010-05-05 23:33:33 +00006156 PyStructSequence_SET_ITEM(result, 0,
6157 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6158 PyStructSequence_SET_ITEM(result, 1,
6159 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006160#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006161 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6162 SET_INT(result, 2, ru->ru_maxrss);
6163 SET_INT(result, 3, ru->ru_ixrss);
6164 SET_INT(result, 4, ru->ru_idrss);
6165 SET_INT(result, 5, ru->ru_isrss);
6166 SET_INT(result, 6, ru->ru_minflt);
6167 SET_INT(result, 7, ru->ru_majflt);
6168 SET_INT(result, 8, ru->ru_nswap);
6169 SET_INT(result, 9, ru->ru_inblock);
6170 SET_INT(result, 10, ru->ru_oublock);
6171 SET_INT(result, 11, ru->ru_msgsnd);
6172 SET_INT(result, 12, ru->ru_msgrcv);
6173 SET_INT(result, 13, ru->ru_nsignals);
6174 SET_INT(result, 14, ru->ru_nvcsw);
6175 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006176#undef SET_INT
6177
Victor Stinnerd6f85422010-05-05 23:33:33 +00006178 if (PyErr_Occurred()) {
6179 Py_DECREF(result);
6180 return NULL;
6181 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006182
Victor Stinnerd6f85422010-05-05 23:33:33 +00006183 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006184}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006185#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006186
6187#ifdef HAVE_WAIT3
6188PyDoc_STRVAR(posix_wait3__doc__,
6189"wait3(options) -> (pid, status, rusage)\n\n\
6190Wait for completion of a child process.");
6191
6192static PyObject *
6193posix_wait3(PyObject *self, PyObject *args)
6194{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006195 pid_t pid;
6196 int options;
6197 struct rusage ru;
6198 WAIT_TYPE status;
6199 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006200
Victor Stinnerd6f85422010-05-05 23:33:33 +00006201 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6202 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006203
Victor Stinnerd6f85422010-05-05 23:33:33 +00006204 Py_BEGIN_ALLOW_THREADS
6205 pid = wait3(&status, options, &ru);
6206 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006207
Victor Stinnerd6f85422010-05-05 23:33:33 +00006208 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006209}
6210#endif /* HAVE_WAIT3 */
6211
6212#ifdef HAVE_WAIT4
6213PyDoc_STRVAR(posix_wait4__doc__,
6214"wait4(pid, options) -> (pid, status, rusage)\n\n\
6215Wait for completion of a given child process.");
6216
6217static PyObject *
6218posix_wait4(PyObject *self, PyObject *args)
6219{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006220 pid_t pid;
6221 int options;
6222 struct rusage ru;
6223 WAIT_TYPE status;
6224 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006225
Victor Stinnerd6f85422010-05-05 23:33:33 +00006226 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6227 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006228
Victor Stinnerd6f85422010-05-05 23:33:33 +00006229 Py_BEGIN_ALLOW_THREADS
6230 pid = wait4(pid, &status, options, &ru);
6231 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006232
Victor Stinnerd6f85422010-05-05 23:33:33 +00006233 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006234}
6235#endif /* HAVE_WAIT4 */
6236
Guido van Rossumb6775db1994-08-01 11:34:53 +00006237#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006238PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006239"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006240Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006241
Barry Warsaw53699e91996-12-10 23:23:01 +00006242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006243posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006244{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006245 pid_t pid;
6246 int options;
6247 WAIT_TYPE status;
6248 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006249
Victor Stinnerd6f85422010-05-05 23:33:33 +00006250 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6251 return NULL;
6252 Py_BEGIN_ALLOW_THREADS
6253 pid = waitpid(pid, &status, options);
6254 Py_END_ALLOW_THREADS
6255 if (pid == -1)
6256 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006257
Victor Stinnerd6f85422010-05-05 23:33:33 +00006258 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006259}
6260
Tim Petersab034fa2002-02-01 11:27:43 +00006261#elif defined(HAVE_CWAIT)
6262
6263/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006265"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006266"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006267
6268static PyObject *
6269posix_waitpid(PyObject *self, PyObject *args)
6270{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006271 Py_intptr_t pid;
6272 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006273
Victor Stinnerd6f85422010-05-05 23:33:33 +00006274 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6275 return NULL;
6276 Py_BEGIN_ALLOW_THREADS
6277 pid = _cwait(&status, pid, options);
6278 Py_END_ALLOW_THREADS
6279 if (pid == -1)
6280 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006281
Victor Stinnerd6f85422010-05-05 23:33:33 +00006282 /* shift the status left a byte so this is more like the POSIX waitpid */
6283 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006284}
6285#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006286
Guido van Rossumad0ee831995-03-01 10:34:45 +00006287#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006288PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006289"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006291
Barry Warsaw53699e91996-12-10 23:23:01 +00006292static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006293posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006294{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006295 pid_t pid;
6296 WAIT_TYPE status;
6297 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006298
Victor Stinnerd6f85422010-05-05 23:33:33 +00006299 Py_BEGIN_ALLOW_THREADS
6300 pid = wait(&status);
6301 Py_END_ALLOW_THREADS
6302 if (pid == -1)
6303 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006304
Victor Stinnerd6f85422010-05-05 23:33:33 +00006305 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006306}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006307#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006310PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006311"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006312Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006313
Barry Warsaw53699e91996-12-10 23:23:01 +00006314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006315posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006316{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006317#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006318 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006319#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006320#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006321 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006322#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006323 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006324#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006325#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006326}
6327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Guido van Rossumb6775db1994-08-01 11:34:53 +00006329#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006330PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006331"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006333
Barry Warsaw53699e91996-12-10 23:23:01 +00006334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006335posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006336{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006337 PyObject* v;
6338 char buf[MAXPATHLEN];
6339 char *path;
6340 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006341#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006342 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006343#endif
6344
Victor Stinnerd6f85422010-05-05 23:33:33 +00006345 if (!PyArg_ParseTuple(args, "et:readlink",
6346 Py_FileSystemDefaultEncoding, &path))
6347 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006348#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006349 v = PySequence_GetItem(args, 0);
6350 if (v == NULL) {
6351 PyMem_Free(path);
6352 return NULL;
6353 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006354
Victor Stinnerd6f85422010-05-05 23:33:33 +00006355 if (PyUnicode_Check(v)) {
6356 arg_is_unicode = 1;
6357 }
6358 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006359#endif
6360
Victor Stinnerd6f85422010-05-05 23:33:33 +00006361 Py_BEGIN_ALLOW_THREADS
6362 n = readlink(path, buf, (int) sizeof buf);
6363 Py_END_ALLOW_THREADS
6364 if (n < 0)
6365 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006366
Victor Stinnerd6f85422010-05-05 23:33:33 +00006367 PyMem_Free(path);
6368 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006369#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006370 if (arg_is_unicode) {
6371 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006372
Victor Stinnerd6f85422010-05-05 23:33:33 +00006373 w = PyUnicode_FromEncodedObject(v,
6374 Py_FileSystemDefaultEncoding,
6375 "strict");
6376 if (w != NULL) {
6377 Py_DECREF(v);
6378 v = w;
6379 }
6380 else {
6381 /* fall back to the original byte string, as
6382 discussed in patch #683592 */
6383 PyErr_Clear();
6384 }
6385 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006386#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006387 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006389#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006391
Guido van Rossumb6775db1994-08-01 11:34:53 +00006392#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006393PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006394"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006395Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006396
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006398posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006399{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006400 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006401}
6402#endif /* HAVE_SYMLINK */
6403
6404
6405#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006406#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6407static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006408system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006409{
6410 ULONG value = 0;
6411
6412 Py_BEGIN_ALLOW_THREADS
6413 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6414 Py_END_ALLOW_THREADS
6415
6416 return value;
6417}
6418
6419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006420posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006421{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006422 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006423 return Py_BuildValue("ddddd",
6424 (double)0 /* t.tms_utime / HZ */,
6425 (double)0 /* t.tms_stime / HZ */,
6426 (double)0 /* t.tms_cutime / HZ */,
6427 (double)0 /* t.tms_cstime / HZ */,
6428 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006429}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006430#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006431#define NEED_TICKS_PER_SECOND
6432static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006433static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006434posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006435{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006436 struct tms t;
6437 clock_t c;
6438 errno = 0;
6439 c = times(&t);
6440 if (c == (clock_t) -1)
6441 return posix_error();
6442 return Py_BuildValue("ddddd",
6443 (double)t.tms_utime / ticks_per_second,
6444 (double)t.tms_stime / ticks_per_second,
6445 (double)t.tms_cutime / ticks_per_second,
6446 (double)t.tms_cstime / ticks_per_second,
6447 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006448}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006449#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006450#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006451
6452
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006453#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006454#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006455static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006456posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006457{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006458 FILETIME create, exit, kernel, user;
6459 HANDLE hProc;
6460 hProc = GetCurrentProcess();
6461 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6462 /* The fields of a FILETIME structure are the hi and lo part
6463 of a 64-bit value expressed in 100 nanosecond units.
6464 1e7 is one second in such units; 1e-7 the inverse.
6465 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6466 */
6467 return Py_BuildValue(
6468 "ddddd",
6469 (double)(user.dwHighDateTime*429.4967296 +
6470 user.dwLowDateTime*1e-7),
6471 (double)(kernel.dwHighDateTime*429.4967296 +
6472 kernel.dwLowDateTime*1e-7),
6473 (double)0,
6474 (double)0,
6475 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006476}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006477#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006478
6479#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006481"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006482Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006483#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006485
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006486#ifdef HAVE_GETSID
6487PyDoc_STRVAR(posix_getsid__doc__,
6488"getsid(pid) -> sid\n\n\
6489Call the system call getsid().");
6490
6491static PyObject *
6492posix_getsid(PyObject *self, PyObject *args)
6493{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006494 pid_t pid;
6495 int sid;
6496 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6497 return NULL;
6498 sid = getsid(pid);
6499 if (sid < 0)
6500 return posix_error();
6501 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006502}
6503#endif /* HAVE_GETSID */
6504
6505
Guido van Rossumb6775db1994-08-01 11:34:53 +00006506#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006508"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006509Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006510
Barry Warsaw53699e91996-12-10 23:23:01 +00006511static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006512posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006513{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006514 if (setsid() < 0)
6515 return posix_error();
6516 Py_INCREF(Py_None);
6517 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006518}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006519#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006520
Guido van Rossumb6775db1994-08-01 11:34:53 +00006521#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006522PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006523"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006525
Barry Warsaw53699e91996-12-10 23:23:01 +00006526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006527posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006528{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006529 pid_t pid;
6530 int pgrp;
6531 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6532 return NULL;
6533 if (setpgid(pid, pgrp) < 0)
6534 return posix_error();
6535 Py_INCREF(Py_None);
6536 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006537}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006538#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006540
Guido van Rossumb6775db1994-08-01 11:34:53 +00006541#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006543"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006545
Barry Warsaw53699e91996-12-10 23:23:01 +00006546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006547posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006548{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006549 int fd;
6550 pid_t pgid;
6551 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6552 return NULL;
6553 pgid = tcgetpgrp(fd);
6554 if (pgid < 0)
6555 return posix_error();
6556 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006557}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006558#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006560
Guido van Rossumb6775db1994-08-01 11:34:53 +00006561#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006563"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006564Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006565
Barry Warsaw53699e91996-12-10 23:23:01 +00006566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006567posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006568{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006569 int fd;
6570 pid_t pgid;
6571 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6572 return NULL;
6573 if (tcsetpgrp(fd, pgid) < 0)
6574 return posix_error();
6575 Py_INCREF(Py_None);
6576 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006577}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006578#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006579
Guido van Rossum687dd131993-05-17 08:34:16 +00006580/* Functions acting on file descriptors */
6581
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006583"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006584Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006585
Barry Warsaw53699e91996-12-10 23:23:01 +00006586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006587posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006588{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006589 char *file = NULL;
6590 int flag;
6591 int mode = 0777;
6592 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006593
6594#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006595 Py_UNICODE *wpath;
6596 if (PyArg_ParseTuple(args, "ui|i:mkdir", &wpath, &flag, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006597 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006598 fd = _wopen(wpath, flag, mode);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006599 Py_END_ALLOW_THREADS
6600 if (fd < 0)
6601 return posix_error();
6602 return PyInt_FromLong((long)fd);
6603 }
6604 /* Drop the argument parsing error as narrow strings
6605 are also valid. */
6606 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006607#endif
6608
Victor Stinnerd6f85422010-05-05 23:33:33 +00006609 if (!PyArg_ParseTuple(args, "eti|i",
6610 Py_FileSystemDefaultEncoding, &file,
6611 &flag, &mode))
6612 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006613
Victor Stinnerd6f85422010-05-05 23:33:33 +00006614 Py_BEGIN_ALLOW_THREADS
6615 fd = open(file, flag, mode);
6616 Py_END_ALLOW_THREADS
6617 if (fd < 0)
6618 return posix_error_with_allocated_filename(file);
6619 PyMem_Free(file);
6620 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006621}
6622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006624PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006625"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006626Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006627
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006628/*
6629The underscore at end of function name avoids a name clash with the libc
6630function posix_close.
6631*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006632static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006633posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006634{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006635 int fd, res;
6636 if (!PyArg_ParseTuple(args, "i:close", &fd))
6637 return NULL;
6638 if (!_PyVerify_fd(fd))
6639 return posix_error();
6640 Py_BEGIN_ALLOW_THREADS
6641 res = close(fd);
6642 Py_END_ALLOW_THREADS
6643 if (res < 0)
6644 return posix_error();
6645 Py_INCREF(Py_None);
6646 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006647}
6648
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006649
Victor Stinnerd6f85422010-05-05 23:33:33 +00006650PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006651"closerange(fd_low, fd_high)\n\n\
6652Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6653
6654static PyObject *
6655posix_closerange(PyObject *self, PyObject *args)
6656{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006657 int fd_from, fd_to, i;
6658 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6659 return NULL;
6660 Py_BEGIN_ALLOW_THREADS
6661 for (i = fd_from; i < fd_to; i++)
6662 if (_PyVerify_fd(i))
6663 close(i);
6664 Py_END_ALLOW_THREADS
6665 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006666}
6667
6668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006669PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006670"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006672
Barry Warsaw53699e91996-12-10 23:23:01 +00006673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006674posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006675{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006676 int fd;
6677 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6678 return NULL;
6679 if (!_PyVerify_fd(fd))
6680 return posix_error();
6681 Py_BEGIN_ALLOW_THREADS
6682 fd = dup(fd);
6683 Py_END_ALLOW_THREADS
6684 if (fd < 0)
6685 return posix_error();
6686 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006687}
6688
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006690PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006691"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006692Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006693
Barry Warsaw53699e91996-12-10 23:23:01 +00006694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006695posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006696{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006697 int fd, fd2, res;
6698 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6699 return NULL;
6700 if (!_PyVerify_fd_dup2(fd, fd2))
6701 return posix_error();
6702 Py_BEGIN_ALLOW_THREADS
6703 res = dup2(fd, fd2);
6704 Py_END_ALLOW_THREADS
6705 if (res < 0)
6706 return posix_error();
6707 Py_INCREF(Py_None);
6708 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006709}
6710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006711
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006712PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006713"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006714Set the current position of a file descriptor.\n\
6715Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006716
Barry Warsaw53699e91996-12-10 23:23:01 +00006717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006718posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006719{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006720 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006721#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006722 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006723#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006724 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006725#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006726 PyObject *posobj;
6727 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6728 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006729#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006730 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6731 switch (how) {
6732 case 0: how = SEEK_SET; break;
6733 case 1: how = SEEK_CUR; break;
6734 case 2: how = SEEK_END; break;
6735 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006736#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006737
6738#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006739 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006740#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006741 pos = PyLong_Check(posobj) ?
6742 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006743#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006744 if (PyErr_Occurred())
6745 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006746
Victor Stinnerd6f85422010-05-05 23:33:33 +00006747 if (!_PyVerify_fd(fd))
6748 return posix_error();
6749 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006750#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006751 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006752#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006753 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006754#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006755 Py_END_ALLOW_THREADS
6756 if (res < 0)
6757 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006758
6759#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006760 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006761#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006762 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006763#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006764}
6765
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006767PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006768"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006769Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006770
Barry Warsaw53699e91996-12-10 23:23:01 +00006771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006772posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006773{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006774 int fd, size, n;
6775 PyObject *buffer;
6776 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6777 return NULL;
6778 if (size < 0) {
6779 errno = EINVAL;
6780 return posix_error();
6781 }
6782 buffer = PyString_FromStringAndSize((char *)NULL, size);
6783 if (buffer == NULL)
6784 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006785 if (!_PyVerify_fd(fd)) {
6786 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006787 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006788 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006789 Py_BEGIN_ALLOW_THREADS
6790 n = read(fd, PyString_AsString(buffer), size);
6791 Py_END_ALLOW_THREADS
6792 if (n < 0) {
6793 Py_DECREF(buffer);
6794 return posix_error();
6795 }
6796 if (n != size)
6797 _PyString_Resize(&buffer, n);
6798 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006799}
6800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006801
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006802PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006803"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006804Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006805
Barry Warsaw53699e91996-12-10 23:23:01 +00006806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006807posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006808{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006809 Py_buffer pbuf;
6810 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006811 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006812
Victor Stinnerd6f85422010-05-05 23:33:33 +00006813 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6814 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006815 if (!_PyVerify_fd(fd)) {
6816 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006817 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006818 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006819 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006820 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006821#if defined(MS_WIN64) || defined(MS_WINDOWS)
6822 if (len > INT_MAX)
6823 len = INT_MAX;
6824 size = write(fd, pbuf.buf, (int)len);
6825#else
6826 size = write(fd, pbuf.buf, len);
6827#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006828 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006829 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006830 if (size < 0)
6831 return posix_error();
6832 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006833}
6834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006835
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006836PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006837"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006838Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006839
Barry Warsaw53699e91996-12-10 23:23:01 +00006840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006841posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006842{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006843 int fd;
6844 STRUCT_STAT st;
6845 int res;
6846 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6847 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006848#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006849 /* on OpenVMS we must ensure that all bytes are written to the file */
6850 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006851#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006852 if (!_PyVerify_fd(fd))
6853 return posix_error();
6854 Py_BEGIN_ALLOW_THREADS
6855 res = FSTAT(fd, &st);
6856 Py_END_ALLOW_THREADS
6857 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006858#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006859 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006860#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006861 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006862#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006863 }
Tim Peters5aa91602002-01-30 05:46:57 +00006864
Victor Stinnerd6f85422010-05-05 23:33:33 +00006865 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006866}
6867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006869PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006870"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006871Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006872
Barry Warsaw53699e91996-12-10 23:23:01 +00006873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006874posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006875{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006876 int fd;
6877 char *orgmode = "r";
6878 int bufsize = -1;
6879 FILE *fp;
6880 PyObject *f;
6881 char *mode;
6882 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6883 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006884
Victor Stinnerd6f85422010-05-05 23:33:33 +00006885 /* Sanitize mode. See fileobject.c */
6886 mode = PyMem_MALLOC(strlen(orgmode)+3);
6887 if (!mode) {
6888 PyErr_NoMemory();
6889 return NULL;
6890 }
6891 strcpy(mode, orgmode);
6892 if (_PyFile_SanitizeMode(mode)) {
6893 PyMem_FREE(mode);
6894 return NULL;
6895 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006896 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006897 PyMem_FREE(mode);
6898 return posix_error();
6899 }
6900#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6901 {
6902 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006903 const char *msg;
6904 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006905 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6906 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006907 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006908 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006909 EISDIR, msg, "<fdopen>");
6910 if (exc) {
6911 PyErr_SetObject(PyExc_IOError, exc);
6912 Py_DECREF(exc);
6913 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006914 return NULL;
6915 }
6916 }
6917#endif
Benjamin Petersond3035d52016-12-03 13:03:18 -08006918 /* The dummy filename used here must be kept in sync with the value
6919 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6920 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
Benjamin Petersone95048e2016-12-03 13:05:40 -08006921 if (f == NULL) {
Benjamin Peterson9ea8faf2016-12-03 13:07:47 -08006922 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006923 return NULL;
Benjamin Petersone95048e2016-12-03 13:05:40 -08006924 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006925 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006926#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006927 if (mode[0] == 'a') {
6928 /* try to make sure the O_APPEND flag is set */
6929 int flags;
6930 flags = fcntl(fd, F_GETFL);
6931 if (flags != -1)
6932 fcntl(fd, F_SETFL, flags | O_APPEND);
6933 fp = fdopen(fd, mode);
6934 if (fp == NULL && flags != -1)
6935 /* restore old mode if fdopen failed */
6936 fcntl(fd, F_SETFL, flags);
6937 } else {
6938 fp = fdopen(fd, mode);
6939 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006940#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006941 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006942#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006943 Py_END_ALLOW_THREADS
6944 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006945 if (fp == NULL) {
6946 Py_DECREF(f);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006947 return posix_error();
Benjamin Petersond3035d52016-12-03 13:03:18 -08006948 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006949 /* We now know we will succeed, so initialize the file object. */
6950 ((PyFileObject *)f)->f_fp = fp;
6951 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006952 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006953}
6954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006955PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006956"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006957Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006959
6960static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006961posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006962{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006963 int fd;
6964 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6965 return NULL;
6966 if (!_PyVerify_fd(fd))
6967 return PyBool_FromLong(0);
6968 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006969}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006970
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006971#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006974Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006975
Barry Warsaw53699e91996-12-10 23:23:01 +00006976static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006977posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006978{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006979#if defined(PYOS_OS2)
6980 HFILE read, write;
6981 APIRET rc;
6982
Victor Stinnerd6f85422010-05-05 23:33:33 +00006983 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006984 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006985 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006986 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006987 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006988
6989 return Py_BuildValue("(ii)", read, write);
6990#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006991#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006992 int fds[2];
6993 int res;
6994 Py_BEGIN_ALLOW_THREADS
6995 res = pipe(fds);
6996 Py_END_ALLOW_THREADS
6997 if (res != 0)
6998 return posix_error();
6999 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007000#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00007001 HANDLE read, write;
7002 int read_fd, write_fd;
7003 BOOL ok;
7004 Py_BEGIN_ALLOW_THREADS
7005 ok = CreatePipe(&read, &write, NULL, 0);
7006 Py_END_ALLOW_THREADS
7007 if (!ok)
7008 return win32_error("CreatePipe", NULL);
7009 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7010 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7011 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007012#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007013#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007014}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007015#endif /* HAVE_PIPE */
7016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007017
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007018#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007019PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007020"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007022
Barry Warsaw53699e91996-12-10 23:23:01 +00007023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007024posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007025{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007026 char *filename;
7027 int mode = 0666;
7028 int res;
7029 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7030 return NULL;
7031 Py_BEGIN_ALLOW_THREADS
7032 res = mkfifo(filename, mode);
7033 Py_END_ALLOW_THREADS
7034 if (res < 0)
7035 return posix_error();
7036 Py_INCREF(Py_None);
7037 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007038}
7039#endif
7040
7041
Neal Norwitz11690112002-07-30 01:08:28 +00007042#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007043PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007044"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007045Create a filesystem node (file, device special file or named pipe)\n\
7046named filename. mode specifies both the permissions to use and the\n\
7047type of node to be created, being combined (bitwise OR) with one of\n\
7048S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007049device defines the newly created device special file (probably using\n\
7050os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007051
7052
7053static PyObject *
7054posix_mknod(PyObject *self, PyObject *args)
7055{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007056 char *filename;
7057 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007058 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007059 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007060 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7061 &filename, &mode,
7062 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007063 return NULL;
7064 Py_BEGIN_ALLOW_THREADS
7065 res = mknod(filename, mode, device);
7066 Py_END_ALLOW_THREADS
7067 if (res < 0)
7068 return posix_error();
7069 Py_INCREF(Py_None);
7070 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007071}
7072#endif
7073
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007074#ifdef HAVE_DEVICE_MACROS
7075PyDoc_STRVAR(posix_major__doc__,
7076"major(device) -> major number\n\
7077Extracts a device major number from a raw device number.");
7078
7079static PyObject *
7080posix_major(PyObject *self, PyObject *args)
7081{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007082 dev_t device;
7083 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007084 return NULL;
7085 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007086}
7087
7088PyDoc_STRVAR(posix_minor__doc__,
7089"minor(device) -> minor number\n\
7090Extracts a device minor number from a raw device number.");
7091
7092static PyObject *
7093posix_minor(PyObject *self, PyObject *args)
7094{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007095 dev_t device;
7096 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007097 return NULL;
7098 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007099}
7100
7101PyDoc_STRVAR(posix_makedev__doc__,
7102"makedev(major, minor) -> device number\n\
7103Composes a raw device number from the major and minor device numbers.");
7104
7105static PyObject *
7106posix_makedev(PyObject *self, PyObject *args)
7107{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007108 int major, minor;
7109 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7110 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007111 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007112}
7113#endif /* device macros */
7114
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007115
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007116#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007117PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007118"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007119Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007120
Barry Warsaw53699e91996-12-10 23:23:01 +00007121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007122posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007123{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007124 int fd;
7125 off_t length;
7126 int res;
7127 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007128
Victor Stinnerd6f85422010-05-05 23:33:33 +00007129 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7130 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007131
7132#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007133 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007134#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007135 length = PyLong_Check(lenobj) ?
7136 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007137#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007138 if (PyErr_Occurred())
7139 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007140
Victor Stinnerd6f85422010-05-05 23:33:33 +00007141 Py_BEGIN_ALLOW_THREADS
7142 res = ftruncate(fd, length);
7143 Py_END_ALLOW_THREADS
7144 if (res < 0)
7145 return posix_error();
7146 Py_INCREF(Py_None);
7147 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007148}
7149#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007150
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007151#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007152PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007153"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007154Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007155
Fred Drake762e2061999-08-26 17:23:54 +00007156/* Save putenv() parameters as values here, so we can collect them when they
7157 * get re-set with another call for the same key. */
7158static PyObject *posix_putenv_garbage;
7159
Tim Peters5aa91602002-01-30 05:46:57 +00007160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007161posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007162{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007163 char *s1, *s2;
7164 char *newenv;
7165 PyObject *newstr;
7166 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007167
Victor Stinnerd6f85422010-05-05 23:33:33 +00007168 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7169 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007170
7171#if defined(PYOS_OS2)
7172 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7173 APIRET rc;
7174
Guido van Rossumd48f2521997-12-05 22:19:34 +00007175 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7176 if (rc != NO_ERROR)
7177 return os2_error(rc);
7178
7179 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7180 APIRET rc;
7181
Guido van Rossumd48f2521997-12-05 22:19:34 +00007182 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7183 if (rc != NO_ERROR)
7184 return os2_error(rc);
7185 } else {
7186#endif
7187
Victor Stinnerd6f85422010-05-05 23:33:33 +00007188 /* XXX This can leak memory -- not easy to fix :-( */
7189 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007190#ifdef MS_WINDOWS
7191 if (_MAX_ENV < (len - 1)) {
7192 PyErr_Format(PyExc_ValueError,
7193 "the environment variable is longer than %u bytes",
7194 _MAX_ENV);
7195 return NULL;
7196 }
7197#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007198 /* len includes space for a trailing \0; the size arg to
7199 PyString_FromStringAndSize does not count that */
7200 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7201 if (newstr == NULL)
7202 return PyErr_NoMemory();
7203 newenv = PyString_AS_STRING(newstr);
7204 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7205 if (putenv(newenv)) {
7206 Py_DECREF(newstr);
7207 posix_error();
7208 return NULL;
7209 }
7210 /* Install the first arg and newstr in posix_putenv_garbage;
7211 * this will cause previous value to be collected. This has to
7212 * happen after the real putenv() call because the old value
7213 * was still accessible until then. */
7214 if (PyDict_SetItem(posix_putenv_garbage,
7215 PyTuple_GET_ITEM(args, 0), newstr)) {
7216 /* really not much we can do; just leak */
7217 PyErr_Clear();
7218 }
7219 else {
7220 Py_DECREF(newstr);
7221 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007222
7223#if defined(PYOS_OS2)
7224 }
7225#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007226 Py_INCREF(Py_None);
7227 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007228}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007229#endif /* putenv */
7230
Guido van Rossumc524d952001-10-19 01:31:59 +00007231#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007232PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007233"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007234Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007235
7236static PyObject *
7237posix_unsetenv(PyObject *self, PyObject *args)
7238{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007239 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007240#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007241 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007242#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007243
Victor Stinnerd6f85422010-05-05 23:33:33 +00007244 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7245 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007246
Charles-François Natali93a11752011-11-27 13:01:35 +01007247#ifdef HAVE_BROKEN_UNSETENV
7248 unsetenv(s1);
7249#else
Victor Stinner53853c32011-11-22 22:20:13 +01007250 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007251 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007252 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007253#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007254
Victor Stinnerd6f85422010-05-05 23:33:33 +00007255 /* Remove the key from posix_putenv_garbage;
7256 * this will cause it to be collected. This has to
7257 * happen after the real unsetenv() call because the
7258 * old value was still accessible until then.
7259 */
7260 if (PyDict_DelItem(posix_putenv_garbage,
7261 PyTuple_GET_ITEM(args, 0))) {
7262 /* really not much we can do; just leak */
7263 PyErr_Clear();
7264 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007265
Victor Stinnerd6f85422010-05-05 23:33:33 +00007266 Py_INCREF(Py_None);
7267 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007268}
7269#endif /* unsetenv */
7270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007271PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007272"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007273Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007274
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007276posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007278 int code;
7279 char *message;
7280 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7281 return NULL;
7282 message = strerror(code);
7283 if (message == NULL) {
7284 PyErr_SetString(PyExc_ValueError,
7285 "strerror() argument out of range");
7286 return NULL;
7287 }
7288 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007289}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007290
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007291
Guido van Rossumc9641791998-08-04 15:26:23 +00007292#ifdef HAVE_SYS_WAIT_H
7293
Fred Drake106c1a02002-04-23 15:58:02 +00007294#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007295PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007296"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007297Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007298
7299static PyObject *
7300posix_WCOREDUMP(PyObject *self, PyObject *args)
7301{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007302 WAIT_TYPE status;
7303 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007304
Victor Stinnerd6f85422010-05-05 23:33:33 +00007305 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7306 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007307
Victor Stinnerd6f85422010-05-05 23:33:33 +00007308 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007309}
7310#endif /* WCOREDUMP */
7311
7312#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007313PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007314"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007315Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007316job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007317
7318static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007319posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007320{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007321 WAIT_TYPE status;
7322 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007323
Victor Stinnerd6f85422010-05-05 23:33:33 +00007324 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7325 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007326
Victor Stinnerd6f85422010-05-05 23:33:33 +00007327 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007328}
7329#endif /* WIFCONTINUED */
7330
Guido van Rossumc9641791998-08-04 15:26:23 +00007331#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007332PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007333"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007334Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007335
7336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007337posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007338{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007339 WAIT_TYPE status;
7340 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007341
Victor Stinnerd6f85422010-05-05 23:33:33 +00007342 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7343 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007344
Victor Stinnerd6f85422010-05-05 23:33:33 +00007345 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007346}
7347#endif /* WIFSTOPPED */
7348
7349#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007350PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007351"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007352Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007353
7354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007355posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007356{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007357 WAIT_TYPE status;
7358 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007359
Victor Stinnerd6f85422010-05-05 23:33:33 +00007360 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7361 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007362
Victor Stinnerd6f85422010-05-05 23:33:33 +00007363 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007364}
7365#endif /* WIFSIGNALED */
7366
7367#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007368PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007369"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007370Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007371system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007372
7373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007374posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007375{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007376 WAIT_TYPE status;
7377 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007378
Victor Stinnerd6f85422010-05-05 23:33:33 +00007379 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7380 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007381
Victor Stinnerd6f85422010-05-05 23:33:33 +00007382 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007383}
7384#endif /* WIFEXITED */
7385
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007386#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007387PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007388"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007389Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007390
7391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007392posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007393{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007394 WAIT_TYPE status;
7395 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007396
Victor Stinnerd6f85422010-05-05 23:33:33 +00007397 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7398 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007399
Victor Stinnerd6f85422010-05-05 23:33:33 +00007400 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007401}
7402#endif /* WEXITSTATUS */
7403
7404#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007405PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007406"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007407Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007408value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007409
7410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007411posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007412{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007413 WAIT_TYPE status;
7414 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007415
Victor Stinnerd6f85422010-05-05 23:33:33 +00007416 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7417 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007418
Victor Stinnerd6f85422010-05-05 23:33:33 +00007419 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007420}
7421#endif /* WTERMSIG */
7422
7423#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007424PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007425"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007426Return the signal that stopped the process that provided\n\
7427the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007428
7429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007430posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007431{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007432 WAIT_TYPE status;
7433 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007434
Victor Stinnerd6f85422010-05-05 23:33:33 +00007435 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7436 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007437
Victor Stinnerd6f85422010-05-05 23:33:33 +00007438 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007439}
7440#endif /* WSTOPSIG */
7441
7442#endif /* HAVE_SYS_WAIT_H */
7443
7444
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007445#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007446#ifdef _SCO_DS
7447/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7448 needed definitions in sys/statvfs.h */
7449#define _SVID3
7450#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007451#include <sys/statvfs.h>
7452
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007453static PyObject*
7454_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007455 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7456 if (v == NULL)
7457 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007458
7459#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007460 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7461 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7462 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7463 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7464 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7465 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7466 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7467 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7468 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7469 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007470#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007471 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7472 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7473 PyStructSequence_SET_ITEM(v, 2,
7474 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7475 PyStructSequence_SET_ITEM(v, 3,
7476 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7477 PyStructSequence_SET_ITEM(v, 4,
7478 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7479 PyStructSequence_SET_ITEM(v, 5,
7480 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7481 PyStructSequence_SET_ITEM(v, 6,
7482 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7483 PyStructSequence_SET_ITEM(v, 7,
7484 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7485 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7486 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007487#endif
7488
Victor Stinnerd6f85422010-05-05 23:33:33 +00007489 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007490}
7491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007492PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007493"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007494Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007495
7496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007497posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007498{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007499 int fd, res;
7500 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007501
Victor Stinnerd6f85422010-05-05 23:33:33 +00007502 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7503 return NULL;
7504 Py_BEGIN_ALLOW_THREADS
7505 res = fstatvfs(fd, &st);
7506 Py_END_ALLOW_THREADS
7507 if (res != 0)
7508 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007509
Victor Stinnerd6f85422010-05-05 23:33:33 +00007510 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007511}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007512#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007513
7514
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007515#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007516#include <sys/statvfs.h>
7517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007518PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007519"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007520Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007521
7522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007523posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007524{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007525 char *path;
7526 int res;
7527 struct statvfs st;
7528 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7529 return NULL;
7530 Py_BEGIN_ALLOW_THREADS
7531 res = statvfs(path, &st);
7532 Py_END_ALLOW_THREADS
7533 if (res != 0)
7534 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007535
Victor Stinnerd6f85422010-05-05 23:33:33 +00007536 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007537}
7538#endif /* HAVE_STATVFS */
7539
7540
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007541#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007542PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007543"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007544Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007545The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007546or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007547
7548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007549posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007550{
7551 PyObject *result = NULL;
7552 char *dir = NULL;
7553 char *pfx = NULL;
7554 char *name;
7555
7556 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007557 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007558
7559 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007560 "tempnam is a potential security risk to your program") < 0)
7561 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007562
Antoine Pitroub0614612011-01-02 20:04:52 +00007563 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7564 "use the tempfile module", 1) < 0)
7565 return NULL;
7566
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007567#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007568 name = _tempnam(dir, pfx);
7569#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007571#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007573 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007574 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007575 free(name);
7576 return result;
7577}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007578#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007579
7580
7581#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007582PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007583"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007584Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007585
7586static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007587posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007588{
7589 FILE *fp;
7590
Antoine Pitroub0614612011-01-02 20:04:52 +00007591 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7592 "use the tempfile module", 1) < 0)
7593 return NULL;
7594
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007595 fp = tmpfile();
7596 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007597 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007598 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007599}
7600#endif
7601
7602
7603#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007604PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007605"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007606Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007607
7608static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007609posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007610{
7611 char buffer[L_tmpnam];
7612 char *name;
7613
Skip Montanaro95618b52001-08-18 18:52:10 +00007614 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007615 "tmpnam is a potential security risk to your program") < 0)
7616 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007617
Antoine Pitroub0614612011-01-02 20:04:52 +00007618 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7619 "use the tempfile module", 1) < 0)
7620 return NULL;
7621
Greg Wardb48bc172000-03-01 21:51:56 +00007622#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623 name = tmpnam_r(buffer);
7624#else
7625 name = tmpnam(buffer);
7626#endif
7627 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007628 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007629#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007630 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007632 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007633#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007634 );
7635 PyErr_SetObject(PyExc_OSError, err);
7636 Py_XDECREF(err);
7637 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007638 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007639 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007640}
7641#endif
7642
7643
Fred Drakec9680921999-12-13 16:37:25 +00007644/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7645 * It maps strings representing configuration variable names to
7646 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007647 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007648 * rarely-used constants. There are three separate tables that use
7649 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007650 *
7651 * This code is always included, even if none of the interfaces that
7652 * need it are included. The #if hackery needed to avoid it would be
7653 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007654 */
7655struct constdef {
7656 char *name;
7657 long value;
7658};
7659
Fred Drake12c6e2d1999-12-14 21:25:03 +00007660static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007661conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007662 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007663{
7664 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007665 *valuep = PyInt_AS_LONG(arg);
7666 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007667 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007668 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007669 /* look up the value in the table using a binary search */
7670 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007671 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007672 size_t hi = tablesize;
7673 int cmp;
7674 char *confname = PyString_AS_STRING(arg);
7675 while (lo < hi) {
7676 mid = (lo + hi) / 2;
7677 cmp = strcmp(confname, table[mid].name);
7678 if (cmp < 0)
7679 hi = mid;
7680 else if (cmp > 0)
7681 lo = mid + 1;
7682 else {
7683 *valuep = table[mid].value;
7684 return 1;
7685 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007686 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007687 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007688 }
7689 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007690 PyErr_SetString(PyExc_TypeError,
7691 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007692 return 0;
7693}
7694
7695
7696#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7697static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007698#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007699 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007700#endif
7701#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007702 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007703#endif
Fred Drakec9680921999-12-13 16:37:25 +00007704#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007705 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007706#endif
7707#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007708 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007709#endif
7710#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007711 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007712#endif
7713#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007714 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007715#endif
7716#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007717 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007718#endif
7719#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007720 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007721#endif
7722#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007723 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007724#endif
7725#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007726 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007727#endif
7728#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007729 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007730#endif
7731#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007732 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007733#endif
7734#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007735 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007736#endif
7737#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007738 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007739#endif
7740#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007741 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007742#endif
7743#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007744 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007745#endif
7746#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007747 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007748#endif
7749};
7750
Fred Drakec9680921999-12-13 16:37:25 +00007751static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007752conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007753{
7754 return conv_confname(arg, valuep, posix_constants_pathconf,
7755 sizeof(posix_constants_pathconf)
7756 / sizeof(struct constdef));
7757}
7758#endif
7759
7760#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007761PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007762"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007763Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007764If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007765
7766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007767posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007768{
7769 PyObject *result = NULL;
7770 int name, fd;
7771
Fred Drake12c6e2d1999-12-14 21:25:03 +00007772 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7773 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007774 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007775
Stefan Krah93f7a322010-11-26 17:35:50 +00007776 errno = 0;
7777 limit = fpathconf(fd, name);
7778 if (limit == -1 && errno != 0)
7779 posix_error();
7780 else
7781 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007782 }
7783 return result;
7784}
7785#endif
7786
7787
7788#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007789PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007790"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007791Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007792If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007793
7794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007795posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007796{
7797 PyObject *result = NULL;
7798 int name;
7799 char *path;
7800
7801 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7802 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007803 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007804
Victor Stinnerd6f85422010-05-05 23:33:33 +00007805 errno = 0;
7806 limit = pathconf(path, name);
7807 if (limit == -1 && errno != 0) {
7808 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007809 /* could be a path or name problem */
7810 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007811 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007812 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 }
7814 else
7815 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007816 }
7817 return result;
7818}
7819#endif
7820
7821#ifdef HAVE_CONFSTR
7822static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007823#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007824 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007825#endif
7826#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007827 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007828#endif
7829#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007830 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007831#endif
7832#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007833 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007834#endif
7835#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007836 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007837#endif
Fred Drakec9680921999-12-13 16:37:25 +00007838#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007839 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007840#endif
7841#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007842 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007843#endif
7844#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007845 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007846#endif
7847#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007848 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007849#endif
7850#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007851 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007852#endif
7853#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007854 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007855#endif
7856#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007857 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007858#endif
7859#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007860 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007861#endif
Fred Draked86ed291999-12-15 15:34:33 +00007862#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007863 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007864#endif
Fred Drakec9680921999-12-13 16:37:25 +00007865#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007866 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007867#endif
Fred Draked86ed291999-12-15 15:34:33 +00007868#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007869 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007870#endif
7871#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007872 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007873#endif
7874#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007875 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007876#endif
7877#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007878 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007879#endif
Fred Drakec9680921999-12-13 16:37:25 +00007880#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007881 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007882#endif
7883#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007884 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007885#endif
7886#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007887 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007888#endif
7889#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007890 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007891#endif
7892#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007893 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007894#endif
7895#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007896 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007897#endif
7898#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007899 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007900#endif
7901#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007902 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007903#endif
7904#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007905 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007906#endif
7907#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007908 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007909#endif
7910#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007911 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007912#endif
7913#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007914 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007915#endif
7916#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007917 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007918#endif
7919#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007920 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007921#endif
7922#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007923 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007924#endif
7925#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007926 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007927#endif
Fred Draked86ed291999-12-15 15:34:33 +00007928#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007929 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007930#endif
7931#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007932 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007933#endif
7934#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007935 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007936#endif
7937#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007938 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007939#endif
7940#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007941 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007942#endif
7943#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007944 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007945#endif
7946#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007947 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007948#endif
7949#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007950 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007951#endif
7952#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007953 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007954#endif
7955#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007956 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007957#endif
7958#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007959 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007960#endif
7961#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007962 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007963#endif
7964#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007965 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007966#endif
Fred Drakec9680921999-12-13 16:37:25 +00007967};
7968
7969static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007970conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007971{
7972 return conv_confname(arg, valuep, posix_constants_confstr,
7973 sizeof(posix_constants_confstr)
7974 / sizeof(struct constdef));
7975}
7976
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007977PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007978"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007979Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007980
7981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007982posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007983{
7984 PyObject *result = NULL;
7985 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007986 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007987
7988 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007989 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007990
Victor Stinnerd6f85422010-05-05 23:33:33 +00007991 errno = 0;
7992 len = confstr(name, buffer, sizeof(buffer));
7993 if (len == 0) {
7994 if (errno) {
7995 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007996 }
7997 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007998 result = Py_None;
7999 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00008000 }
8001 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00008002 else {
8003 if ((unsigned int)len >= sizeof(buffer)) {
8004 result = PyString_FromStringAndSize(NULL, len-1);
8005 if (result != NULL)
8006 confstr(name, PyString_AS_STRING(result), len);
8007 }
8008 else
8009 result = PyString_FromStringAndSize(buffer, len-1);
8010 }
8011 }
Fred Drakec9680921999-12-13 16:37:25 +00008012 return result;
8013}
8014#endif
8015
8016
8017#ifdef HAVE_SYSCONF
8018static struct constdef posix_constants_sysconf[] = {
8019#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008020 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008021#endif
8022#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008023 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008024#endif
8025#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008026 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008027#endif
8028#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008029 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008030#endif
8031#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008032 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008033#endif
8034#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008035 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008036#endif
8037#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008038 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008039#endif
8040#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008041 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008042#endif
8043#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008044 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008045#endif
8046#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008047 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008048#endif
Fred Draked86ed291999-12-15 15:34:33 +00008049#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008050 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008051#endif
8052#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008053 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008054#endif
Fred Drakec9680921999-12-13 16:37:25 +00008055#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008056 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008057#endif
Fred Drakec9680921999-12-13 16:37:25 +00008058#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008059 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008060#endif
8061#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008062 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
8064#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008065 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008066#endif
8067#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008068 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008069#endif
8070#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008071 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008072#endif
Fred Draked86ed291999-12-15 15:34:33 +00008073#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008074 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008075#endif
Fred Drakec9680921999-12-13 16:37:25 +00008076#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008077 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008078#endif
8079#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008080 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
8082#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008083 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008084#endif
8085#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008086 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008087#endif
8088#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008089 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008090#endif
Fred Draked86ed291999-12-15 15:34:33 +00008091#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008092 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008093#endif
Fred Drakec9680921999-12-13 16:37:25 +00008094#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008095 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008096#endif
8097#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008098 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008099#endif
8100#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008101 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008102#endif
8103#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008104 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008105#endif
8106#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008107 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008108#endif
8109#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008110 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008111#endif
8112#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008113 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008114#endif
8115#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008116 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008117#endif
8118#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008119 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008120#endif
8121#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008122 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008123#endif
8124#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008125 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008126#endif
8127#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008128 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008129#endif
8130#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008131 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008132#endif
8133#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008134 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008135#endif
8136#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008137 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008138#endif
8139#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008140 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008141#endif
8142#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008143 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008144#endif
8145#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008146 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008147#endif
8148#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008149 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008150#endif
8151#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008152 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008153#endif
8154#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008155 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008156#endif
8157#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008158 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008159#endif
8160#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008161 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008162#endif
Fred Draked86ed291999-12-15 15:34:33 +00008163#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008164 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008165#endif
Fred Drakec9680921999-12-13 16:37:25 +00008166#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008167 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008168#endif
8169#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008170 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008171#endif
8172#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008173 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008174#endif
Fred Draked86ed291999-12-15 15:34:33 +00008175#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008176 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008177#endif
Fred Drakec9680921999-12-13 16:37:25 +00008178#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008179 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008180#endif
Fred Draked86ed291999-12-15 15:34:33 +00008181#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008182 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008183#endif
8184#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008185 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008186#endif
Fred Drakec9680921999-12-13 16:37:25 +00008187#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008188 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008189#endif
8190#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008191 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008192#endif
8193#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008194 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008195#endif
8196#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008197 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008198#endif
Fred Draked86ed291999-12-15 15:34:33 +00008199#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008200 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008201#endif
Fred Drakec9680921999-12-13 16:37:25 +00008202#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008203 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008204#endif
8205#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008206 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008207#endif
8208#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008209 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008210#endif
8211#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008212 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008213#endif
8214#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008215 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008218 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008221 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
Fred Draked86ed291999-12-15 15:34:33 +00008223#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008224 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008225#endif
Fred Drakec9680921999-12-13 16:37:25 +00008226#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008227 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008230 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
Fred Draked86ed291999-12-15 15:34:33 +00008232#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008233 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008234#endif
Fred Drakec9680921999-12-13 16:37:25 +00008235#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008236 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008239 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008242 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008245 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
8247#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008248 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008251 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008254 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008257 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
8259#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008260 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008261#endif
Fred Draked86ed291999-12-15 15:34:33 +00008262#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008263 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008264#endif
8265#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008266 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008267#endif
Fred Drakec9680921999-12-13 16:37:25 +00008268#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008269 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008270#endif
8271#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008272 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008273#endif
8274#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008275 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
8277#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008278 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008281 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008284 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
8286#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008287 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008288#endif
8289#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008290 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008291#endif
8292#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008293 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008294#endif
8295#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008296 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008297#endif
8298#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008299 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008300#endif
8301#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008302 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008303#endif
8304#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008305 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008306#endif
8307#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008308 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008309#endif
8310#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008311 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008312#endif
8313#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008314 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008315#endif
8316#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008317 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008318#endif
8319#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008320 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008321#endif
8322#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008323 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008324#endif
8325#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008326 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008327#endif
8328#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008329 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008330#endif
8331#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008332 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008333#endif
8334#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008335 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008336#endif
8337#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008338 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008339#endif
8340#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008341 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008342#endif
8343#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008344 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008345#endif
8346#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008347 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008348#endif
8349#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008350 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008351#endif
8352#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008353 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008354#endif
8355#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008356 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008357#endif
8358#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008359 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008360#endif
8361#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008362 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008363#endif
8364#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008365 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008366#endif
8367#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008368 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008369#endif
8370#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008371 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008372#endif
Fred Draked86ed291999-12-15 15:34:33 +00008373#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008374 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008375#endif
Fred Drakec9680921999-12-13 16:37:25 +00008376#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008377 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008378#endif
8379#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008380 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008381#endif
8382#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008383 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008384#endif
8385#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008386 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008387#endif
8388#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008389 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008390#endif
8391#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008392 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008393#endif
8394#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008395 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008396#endif
8397#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008398 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008399#endif
8400#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008401 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008402#endif
8403#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008404 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008405#endif
8406#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008407 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008408#endif
8409#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008410 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008411#endif
8412#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008413 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008414#endif
8415#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008416 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008417#endif
8418#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008419 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008420#endif
8421#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008422 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008423#endif
8424#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008425 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008426#endif
8427#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008428 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008429#endif
8430#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008431 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008432#endif
8433#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008434 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008435#endif
8436#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008437 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008438#endif
8439#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008440 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008441#endif
8442#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008443 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008444#endif
8445#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008446 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008447#endif
8448#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008449 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008450#endif
8451#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008452 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008453#endif
8454#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008455 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008456#endif
8457#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008458 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008459#endif
8460#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008461 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008462#endif
8463#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008464 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008465#endif
8466#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008467 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008468#endif
8469#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008470 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008471#endif
8472#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008473 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008474#endif
8475#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008476 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008477#endif
8478#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008479 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008480#endif
8481#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008482 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008483#endif
8484#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008485 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008486#endif
8487#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008488 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008489#endif
8490#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008491 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008492#endif
8493#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008494 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008495#endif
8496#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008497 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008498#endif
8499#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008500 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008501#endif
8502#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008503 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008504#endif
8505#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008506 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008507#endif
8508#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008509 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008510#endif
8511};
8512
8513static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008514conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008515{
8516 return conv_confname(arg, valuep, posix_constants_sysconf,
8517 sizeof(posix_constants_sysconf)
8518 / sizeof(struct constdef));
8519}
8520
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008521PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008522"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008523Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008524
8525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008526posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008527{
8528 PyObject *result = NULL;
8529 int name;
8530
8531 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008532 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008533
Victor Stinner862490a2010-05-06 00:03:44 +00008534 errno = 0;
8535 value = sysconf(name);
8536 if (value == -1 && errno != 0)
8537 posix_error();
8538 else
8539 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008540 }
8541 return result;
8542}
8543#endif
8544
8545
Fred Drakebec628d1999-12-15 18:31:10 +00008546/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008547 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008548 * the exported dictionaries that are used to publish information about the
8549 * names available on the host platform.
8550 *
8551 * Sorting the table at runtime ensures that the table is properly ordered
8552 * when used, even for platforms we're not able to test on. It also makes
8553 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008554 */
Fred Drakebec628d1999-12-15 18:31:10 +00008555
8556static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008557cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008558{
8559 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008560 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008561 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008562 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008563
8564 return strcmp(c1->name, c2->name);
8565}
8566
8567static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008568setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008569 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008570{
Fred Drakebec628d1999-12-15 18:31:10 +00008571 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008572 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008573 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8574 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008575 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008576 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008577
Barry Warsaw3155db32000-04-13 15:20:40 +00008578 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008579 PyObject *o = PyInt_FromLong(table[i].value);
8580 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8581 Py_XDECREF(o);
8582 Py_DECREF(d);
8583 return -1;
8584 }
8585 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008586 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008587 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008588}
8589
Fred Drakebec628d1999-12-15 18:31:10 +00008590/* Return -1 on failure, 0 on success. */
8591static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008592setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008593{
8594#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008595 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008596 sizeof(posix_constants_pathconf)
8597 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008598 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008599 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008600#endif
8601#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008602 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008603 sizeof(posix_constants_confstr)
8604 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008605 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008606 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008607#endif
8608#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008609 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008610 sizeof(posix_constants_sysconf)
8611 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008612 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008613 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008614#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008615 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008616}
Fred Draked86ed291999-12-15 15:34:33 +00008617
8618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008619PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008620"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008621Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008622in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008623
8624static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008625posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008626{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008627 abort();
8628 /*NOTREACHED*/
8629 Py_FatalError("abort() called from Python code didn't abort!");
8630 return NULL;
8631}
Fred Drakebec628d1999-12-15 18:31:10 +00008632
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008633#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008634PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008635"startfile(filepath [, operation]) - Start a file with its associated\n\
8636application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008637\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008638When \"operation\" is not specified or \"open\", this acts like\n\
8639double-clicking the file in Explorer, or giving the file name as an\n\
8640argument to the DOS \"start\" command: the file is opened with whatever\n\
8641application (if any) its extension is associated.\n\
8642When another \"operation\" is given, it specifies what should be done with\n\
8643the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008644\n\
8645startfile returns as soon as the associated application is launched.\n\
8646There is no option to wait for the application to close, and no way\n\
8647to retrieve the application's exit status.\n\
8648\n\
8649The filepath is relative to the current directory. If you want to use\n\
8650an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008651the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008652
8653static PyObject *
8654win32_startfile(PyObject *self, PyObject *args)
8655{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008656 char *filepath;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008657 Py_UNICODE *wpath;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008658 char *operation = NULL;
8659 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008660
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008661 PyObject *woperation = NULL;
8662 if (!PyArg_ParseTuple(args, "u|s:startfile",
8663 &wpath, &operation)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008664 PyErr_Clear();
8665 goto normal;
8666 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008667
Victor Stinnerd6f85422010-05-05 23:33:33 +00008668 if (operation) {
8669 woperation = PyUnicode_DecodeASCII(operation,
8670 strlen(operation), NULL);
8671 if (!woperation) {
8672 PyErr_Clear();
8673 operation = NULL;
8674 goto normal;
8675 }
8676 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008677
Victor Stinnerd6f85422010-05-05 23:33:33 +00008678 Py_BEGIN_ALLOW_THREADS
8679 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008680 wpath,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008681 NULL, NULL, SW_SHOWNORMAL);
8682 Py_END_ALLOW_THREADS
8683
8684 Py_XDECREF(woperation);
8685 if (rc <= (HINSTANCE)32) {
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008686 PyObject *errval = win32_error_unicode("startfile", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00008687 return errval;
8688 }
8689 Py_INCREF(Py_None);
8690 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008691
8692normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008693 if (!PyArg_ParseTuple(args, "et|s:startfile",
8694 Py_FileSystemDefaultEncoding, &filepath,
8695 &operation))
8696 return NULL;
8697 Py_BEGIN_ALLOW_THREADS
8698 rc = ShellExecute((HWND)0, operation, filepath,
8699 NULL, NULL, SW_SHOWNORMAL);
8700 Py_END_ALLOW_THREADS
8701 if (rc <= (HINSTANCE)32) {
8702 PyObject *errval = win32_error("startfile", filepath);
8703 PyMem_Free(filepath);
8704 return errval;
8705 }
8706 PyMem_Free(filepath);
8707 Py_INCREF(Py_None);
8708 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008709}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008710#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008711
Martin v. Löwis438b5342002-12-27 10:16:42 +00008712#ifdef HAVE_GETLOADAVG
8713PyDoc_STRVAR(posix_getloadavg__doc__,
8714"getloadavg() -> (float, float, float)\n\n\
8715Return the number of processes in the system run queue averaged over\n\
8716the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8717was unobtainable");
8718
8719static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008720posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008721{
8722 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008723 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008724 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8725 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008726 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008727 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008728}
8729#endif
8730
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008731PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008732"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008733Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008734
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008735static PyObject *
8736posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008737{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008738 Py_ssize_t size;
8739 PyObject *result;
8740 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008741
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008742 /* Read arguments */
8743 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008744 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008745 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008746 return PyErr_Format(PyExc_ValueError,
8747 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008748 result = PyBytes_FromStringAndSize(NULL, size);
8749 if (result == NULL)
8750 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008751
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008752 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8753 PyBytes_GET_SIZE(result));
8754 if (ret == -1) {
8755 Py_DECREF(result);
8756 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008757 }
8758 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008759}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008760
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008761#ifdef HAVE_SETRESUID
8762PyDoc_STRVAR(posix_setresuid__doc__,
8763"setresuid(ruid, euid, suid)\n\n\
8764Set the current process's real, effective, and saved user ids.");
8765
8766static PyObject*
8767posix_setresuid (PyObject *self, PyObject *args)
8768{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008769 uid_t ruid, euid, suid;
8770 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8771 _Py_Uid_Converter, &ruid,
8772 _Py_Uid_Converter, &euid,
8773 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008774 return NULL;
8775 if (setresuid(ruid, euid, suid) < 0)
8776 return posix_error();
8777 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008778}
8779#endif
8780
8781#ifdef HAVE_SETRESGID
8782PyDoc_STRVAR(posix_setresgid__doc__,
8783"setresgid(rgid, egid, sgid)\n\n\
8784Set the current process's real, effective, and saved group ids.");
8785
8786static PyObject*
8787posix_setresgid (PyObject *self, PyObject *args)
8788{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008789 gid_t rgid, egid, sgid;
8790 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8791 _Py_Gid_Converter, &rgid,
8792 _Py_Gid_Converter, &egid,
8793 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008794 return NULL;
8795 if (setresgid(rgid, egid, sgid) < 0)
8796 return posix_error();
8797 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008798}
8799#endif
8800
8801#ifdef HAVE_GETRESUID
8802PyDoc_STRVAR(posix_getresuid__doc__,
8803"getresuid() -> (ruid, euid, suid)\n\n\
8804Get tuple of the current process's real, effective, and saved user ids.");
8805
8806static PyObject*
8807posix_getresuid (PyObject *self, PyObject *noargs)
8808{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008809 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008810 if (getresuid(&ruid, &euid, &suid) < 0)
8811 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008812 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8813 _PyInt_FromUid(euid),
8814 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008815}
8816#endif
8817
8818#ifdef HAVE_GETRESGID
8819PyDoc_STRVAR(posix_getresgid__doc__,
8820"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008821Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008822
8823static PyObject*
8824posix_getresgid (PyObject *self, PyObject *noargs)
8825{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008826 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 if (getresgid(&rgid, &egid, &sgid) < 0)
8828 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008829 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8830 _PyInt_FromGid(egid),
8831 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008832}
8833#endif
8834
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008835static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008837#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008838 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008839#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008840 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008841#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008842 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008843#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008844 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008845#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008846 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008847#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008848#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008849 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008850#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008851#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008852 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008853#endif /* HAVE_LCHMOD */
8854#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008855 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008856#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008857#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008858 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008859#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008860#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008862#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008863#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008864 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008865#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008866#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008867 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008868#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008869#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008870 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008871#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008872 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008873#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008874#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008875#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008876 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008877#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008878 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8879 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8880 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008881#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008883#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008884#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008885 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008886#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008887 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8888 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8889 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8890 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008891#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008893#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008894#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008896#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008897 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008898#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008899 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008900#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8902 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8903 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008904#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008905 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008906#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008908#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008909 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8910 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008911#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008912#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008913 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8914 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008915#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008916 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8917 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008918#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008919#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008920#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008921 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008922#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008923#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008925#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008926#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008927 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008928#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008929#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008930 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008931#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008932#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008933 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008934#endif /* HAVE_GETEGID */
8935#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008936 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008937#endif /* HAVE_GETEUID */
8938#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008939 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008940#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008941#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008942 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008944 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008945#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008946 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008947#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008948#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008949 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008950#endif /* HAVE_GETPPID */
8951#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008953#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008954#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008955 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008956#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008957#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008958 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008959#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008960#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008961 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008962#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008963#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008964 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008965#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008966#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008967 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008968#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008969 {"popen2", win32_popen2, METH_VARARGS},
8970 {"popen3", win32_popen3, METH_VARARGS},
8971 {"popen4", win32_popen4, METH_VARARGS},
8972 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8973 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008974#else
8975#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008976 {"popen2", os2emx_popen2, METH_VARARGS},
8977 {"popen3", os2emx_popen3, METH_VARARGS},
8978 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008979#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008980#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008981#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008982#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008983 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008984#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008985#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008986 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008987#endif /* HAVE_SETEUID */
8988#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008989 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008990#endif /* HAVE_SETEGID */
8991#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008992 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008993#endif /* HAVE_SETREUID */
8994#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008995 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008996#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008997#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008998 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008999#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009000#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009001 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009002#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009003#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009004 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009005#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00009006#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009007 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00009008#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009009#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009010 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009011#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009012#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009013 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009014#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009015#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009016 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009017#endif /* HAVE_WAIT3 */
9018#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009019 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009020#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009021#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009022 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009023#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009024#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009025 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009026#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009027#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009028 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009029#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009030#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009031 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009032#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009033#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009034 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009035#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009036#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009038#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009039 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009040 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009041 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9042 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9043 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9044 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9045 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9046 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9047 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9048 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9049 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009050#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009051 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009052#endif
9053#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009054 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009055#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009056#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009057 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009058#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009059#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009060 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9061 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9062 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009063#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009064#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009066#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009067#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009069#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009070#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009071 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009072#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009073 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009074#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009075 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009076#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009077#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009078 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009079#endif
9080#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009081 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009082#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009083#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009084#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009085 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009086#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009087#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009088 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009089#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009090#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009091 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009092#endif /* WIFSTOPPED */
9093#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009094 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009095#endif /* WIFSIGNALED */
9096#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009098#endif /* WIFEXITED */
9099#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009101#endif /* WEXITSTATUS */
9102#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009103 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009104#endif /* WTERMSIG */
9105#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009106 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009107#endif /* WSTOPSIG */
9108#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009109#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009110 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009111#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009112#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009113 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009114#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009115#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009117#endif
9118#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009119 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009120#endif
9121#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009122 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009123#endif
Fred Drakec9680921999-12-13 16:37:25 +00009124#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009126#endif
9127#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009128 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009129#endif
9130#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009131 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009132#endif
9133#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009134 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009135#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009136 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009137#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009139 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009140#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009141#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009142 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009143#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009144#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009145 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009146#endif
9147#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009148 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009149#endif
9150#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009151 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009152#endif
9153#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009154 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009155#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009156 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009157 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009158};
9159
9160
Barry Warsaw4a342091996-12-19 23:50:02 +00009161static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009162ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009163{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009164 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009165}
9166
Guido van Rossumd48f2521997-12-05 22:19:34 +00009167#if defined(PYOS_OS2)
9168/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009169static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009170{
9171 APIRET rc;
9172 ULONG values[QSV_MAX+1];
9173 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009174 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009175
9176 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009177 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009178 Py_END_ALLOW_THREADS
9179
9180 if (rc != NO_ERROR) {
9181 os2_error(rc);
9182 return -1;
9183 }
9184
Fred Drake4d1e64b2002-04-15 19:40:07 +00009185 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9186 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9187 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9188 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9189 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9190 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9191 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009192
9193 switch (values[QSV_VERSION_MINOR]) {
9194 case 0: ver = "2.00"; break;
9195 case 10: ver = "2.10"; break;
9196 case 11: ver = "2.11"; break;
9197 case 30: ver = "3.00"; break;
9198 case 40: ver = "4.00"; break;
9199 case 50: ver = "5.00"; break;
9200 default:
Tim Peters885d4572001-11-28 20:27:42 +00009201 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009202 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009203 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009204 ver = &tmp[0];
9205 }
9206
9207 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009208 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009209 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009210
9211 /* Add Indicator of Which Drive was Used to Boot the System */
9212 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9213 tmp[1] = ':';
9214 tmp[2] = '\0';
9215
Fred Drake4d1e64b2002-04-15 19:40:07 +00009216 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009217}
9218#endif
9219
Barry Warsaw4a342091996-12-19 23:50:02 +00009220static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009221all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009222{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009223#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009224 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009225#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009226#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009227 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009228#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009229#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009230 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009231#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009232#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009233 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009234#endif
Fred Drakec9680921999-12-13 16:37:25 +00009235#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009236 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009237#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009238#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009239 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009240#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009241#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009242 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009243#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009244#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009245 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009246#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009247#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009248 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009249#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009250#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009251 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009252#endif
9253#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009254 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009255#endif
9256#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009257 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009258#endif
9259#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009260 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009261#endif
9262#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009263 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009264#endif
9265#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009266 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009267#endif
9268#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009269 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009270#endif
9271#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009272 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009273#endif
9274#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009275 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009276#endif
9277#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009278 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009279#endif
9280#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009281 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009282#endif
9283#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009284 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009285#endif
9286#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009287 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009288#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009289#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009290 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009291#endif
9292#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009293 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009294#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009295#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009296 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009297#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009298#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009299 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009300#endif
9301#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009302 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009303#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009304
Tim Peters5aa91602002-01-30 05:46:57 +00009305/* MS Windows */
9306#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009307 /* Don't inherit in child processes. */
9308 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009309#endif
9310#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009311 /* Optimize for short life (keep in memory). */
9312 /* MS forgot to define this one with a non-underscore form too. */
9313 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009314#endif
9315#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009316 /* Automatically delete when last handle is closed. */
9317 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009318#endif
9319#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009320 /* Optimize for random access. */
9321 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009322#endif
9323#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009324 /* Optimize for sequential access. */
9325 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009326#endif
9327
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009328/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009329#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 /* Send a SIGIO signal whenever input or output
9331 becomes available on file descriptor */
9332 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009333#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009334#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009335 /* Direct disk access. */
9336 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009337#endif
9338#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 /* Must be a directory. */
9340 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009341#endif
9342#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009343 /* Do not follow links. */
9344 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009345#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009346#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009347 /* Do not update the access time. */
9348 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009349#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009350
Victor Stinnerd6f85422010-05-05 23:33:33 +00009351 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009352#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009353 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009354#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009355#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009356 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009357#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009358#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009359 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009360#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009361#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009362 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009363#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009364#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009365 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009366#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009367#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009368 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009369#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009370#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009371 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009372#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009373#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009374 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009375#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009376#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009377 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009378#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009379#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009380 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009381#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009382#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009383 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009384#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009385#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009386 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009387#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009388#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009389 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009390#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009391#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009392 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009393#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009394#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009395 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009396#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009397#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009398 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009399#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009400#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009401 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009402#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009403
Guido van Rossum246bc171999-02-01 23:54:31 +00009404#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009405#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009406 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9407 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9408 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9409 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9410 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9411 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9412 if (ins(d, "P_PM", (long)P_PM)) return -1;
9413 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9414 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9415 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9416 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9417 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9418 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9419 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9420 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9421 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9422 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9423 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9424 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9425 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009426#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009427 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9428 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9429 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9430 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9431 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009432#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009433#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009434
Guido van Rossumd48f2521997-12-05 22:19:34 +00009435#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009436 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009437#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009438 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009439}
9440
9441
Tim Peters5aa91602002-01-30 05:46:57 +00009442#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009443#define INITFUNC initnt
9444#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009445
9446#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009447#define INITFUNC initos2
9448#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009449
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009450#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009451#define INITFUNC initposix
9452#define MODNAME "posix"
9453#endif
9454
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009455PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009456INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009457{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009458 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009459
Victor Stinnerd6f85422010-05-05 23:33:33 +00009460 m = Py_InitModule3(MODNAME,
9461 posix_methods,
9462 posix__doc__);
9463 if (m == NULL)
9464 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009465
Victor Stinnerd6f85422010-05-05 23:33:33 +00009466 /* Initialize environ dictionary */
9467 v = convertenviron();
9468 Py_XINCREF(v);
9469 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9470 return;
9471 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009472
Victor Stinnerd6f85422010-05-05 23:33:33 +00009473 if (all_ins(m))
9474 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009475
Victor Stinnerd6f85422010-05-05 23:33:33 +00009476 if (setup_confname_tables(m))
9477 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009478
Victor Stinnerd6f85422010-05-05 23:33:33 +00009479 Py_INCREF(PyExc_OSError);
9480 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009481
Guido van Rossumb3d39562000-01-31 18:41:26 +00009482#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009483 if (posix_putenv_garbage == NULL)
9484 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009485#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009486
Victor Stinnerd6f85422010-05-05 23:33:33 +00009487 if (!initialized) {
9488 stat_result_desc.name = MODNAME ".stat_result";
9489 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9490 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9491 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9492 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9493 structseq_new = StatResultType.tp_new;
9494 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009495
Victor Stinnerd6f85422010-05-05 23:33:33 +00009496 statvfs_result_desc.name = MODNAME ".statvfs_result";
9497 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009498#ifdef NEED_TICKS_PER_SECOND
9499# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009500 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009501# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009502 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009503# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009504 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009505# endif
9506#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009507 }
9508 Py_INCREF((PyObject*) &StatResultType);
9509 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9510 Py_INCREF((PyObject*) &StatVFSResultType);
9511 PyModule_AddObject(m, "statvfs_result",
9512 (PyObject*) &StatVFSResultType);
9513 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009514
9515#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009516 /*
9517 * Step 2 of weak-linking support on Mac OS X.
9518 *
9519 * The code below removes functions that are not available on the
9520 * currently active platform.
9521 *
9522 * This block allow one to use a python binary that was build on
9523 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9524 * OSX 10.4.
9525 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009526#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009527 if (fstatvfs == NULL) {
9528 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9529 return;
9530 }
9531 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009532#endif /* HAVE_FSTATVFS */
9533
9534#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009535 if (statvfs == NULL) {
9536 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9537 return;
9538 }
9539 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009540#endif /* HAVE_STATVFS */
9541
9542# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009543 if (lchown == NULL) {
9544 if (PyObject_DelAttrString(m, "lchown") == -1) {
9545 return;
9546 }
9547 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009548#endif /* HAVE_LCHOWN */
9549
9550
9551#endif /* __APPLE__ */
9552
Guido van Rossumb6775db1994-08-01 11:34:53 +00009553}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009554
9555#ifdef __cplusplus
9556}
9557#endif
9558
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009559