blob: a06c56e0691f35e456a32eeb30f6faeaafa82c89 [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 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003559 /* Search from index 1 because on Windows starting '=' is allowed for
3560 defining hidden environment variables. */
3561 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3562 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3563 goto fail_2;
3564 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003565 len = PyString_Size(key) + PyString_Size(val) + 2;
3566 p = PyMem_NEW(char, len);
3567 if (p == NULL) {
3568 PyErr_NoMemory();
3569 goto fail_2;
3570 }
3571 PyOS_snprintf(p, len, "%s=%s", k, v);
3572 envlist[envc++] = p;
3573 }
3574 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003575
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003576#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003577 Py_BEGIN_ALLOW_THREADS
3578 spawnval = spawnve(mode, path, argvlist, envlist);
3579 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003580#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003581 if (mode == _OLD_P_OVERLAY)
3582 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003583
Victor Stinnerd6f85422010-05-05 23:33:33 +00003584 Py_BEGIN_ALLOW_THREADS
3585 spawnval = _spawnve(mode, path, argvlist, envlist);
3586 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003587#endif
Tim Peters25059d32001-12-07 20:35:43 +00003588
Victor Stinnerd6f85422010-05-05 23:33:33 +00003589 if (spawnval == -1)
3590 (void) posix_error();
3591 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003592#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003593 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003594#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003596#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003597
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003598 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003599 while (--envc >= 0)
3600 PyMem_DEL(envlist[envc]);
3601 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003602 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003603 free_string_array(argvlist, lastarg);
3604 Py_XDECREF(vals);
3605 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003606 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003607 PyMem_Free(path);
3608 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003609}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003610
3611/* OS/2 supports spawnvp & spawnvpe natively */
3612#if defined(PYOS_OS2)
3613PyDoc_STRVAR(posix_spawnvp__doc__,
3614"spawnvp(mode, file, args)\n\n\
3615Execute the program 'file' in a new process, using the environment\n\
3616search path to find the file.\n\
3617\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003618 mode: mode of process creation\n\
3619 file: executable file name\n\
3620 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003621
3622static PyObject *
3623posix_spawnvp(PyObject *self, PyObject *args)
3624{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003625 char *path;
3626 PyObject *argv;
3627 char **argvlist;
3628 int mode, i, argc;
3629 Py_intptr_t spawnval;
3630 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003631
Victor Stinnerd6f85422010-05-05 23:33:33 +00003632 /* spawnvp has three arguments: (mode, path, argv), where
3633 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003634
Victor Stinnerd6f85422010-05-05 23:33:33 +00003635 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3636 Py_FileSystemDefaultEncoding,
3637 &path, &argv))
3638 return NULL;
3639 if (PyList_Check(argv)) {
3640 argc = PyList_Size(argv);
3641 getitem = PyList_GetItem;
3642 }
3643 else if (PyTuple_Check(argv)) {
3644 argc = PyTuple_Size(argv);
3645 getitem = PyTuple_GetItem;
3646 }
3647 else {
3648 PyErr_SetString(PyExc_TypeError,
3649 "spawnvp() arg 2 must be a tuple or list");
3650 PyMem_Free(path);
3651 return NULL;
3652 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003653
Victor Stinnerd6f85422010-05-05 23:33:33 +00003654 argvlist = PyMem_NEW(char *, argc+1);
3655 if (argvlist == NULL) {
3656 PyMem_Free(path);
3657 return PyErr_NoMemory();
3658 }
3659 for (i = 0; i < argc; i++) {
3660 if (!PyArg_Parse((*getitem)(argv, i), "et",
3661 Py_FileSystemDefaultEncoding,
3662 &argvlist[i])) {
3663 free_string_array(argvlist, i);
3664 PyErr_SetString(
3665 PyExc_TypeError,
3666 "spawnvp() arg 2 must contain only strings");
3667 PyMem_Free(path);
3668 return NULL;
3669 }
3670 }
3671 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003672
Victor Stinnerd6f85422010-05-05 23:33:33 +00003673 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003674#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003675 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003676#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003677 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003678#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003679 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003680
Victor Stinnerd6f85422010-05-05 23:33:33 +00003681 free_string_array(argvlist, argc);
3682 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003683
Victor Stinnerd6f85422010-05-05 23:33:33 +00003684 if (spawnval == -1)
3685 return posix_error();
3686 else
3687 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003688}
3689
3690
3691PyDoc_STRVAR(posix_spawnvpe__doc__,
3692"spawnvpe(mode, file, args, env)\n\n\
3693Execute the program 'file' in a new process, using the environment\n\
3694search path to find the file.\n\
3695\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003696 mode: mode of process creation\n\
3697 file: executable file name\n\
3698 args: tuple or list of arguments\n\
3699 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003700
3701static PyObject *
3702posix_spawnvpe(PyObject *self, PyObject *args)
3703{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003704 char *path;
3705 PyObject *argv, *env;
3706 char **argvlist;
3707 char **envlist;
3708 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3709 int mode, i, pos, argc, envc;
3710 Py_intptr_t spawnval;
3711 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3712 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003713
Victor Stinnerd6f85422010-05-05 23:33:33 +00003714 /* spawnvpe has four arguments: (mode, path, argv, env), where
3715 argv is a list or tuple of strings and env is a dictionary
3716 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003717
Victor Stinnerd6f85422010-05-05 23:33:33 +00003718 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3719 Py_FileSystemDefaultEncoding,
3720 &path, &argv, &env))
3721 return NULL;
3722 if (PyList_Check(argv)) {
3723 argc = PyList_Size(argv);
3724 getitem = PyList_GetItem;
3725 }
3726 else if (PyTuple_Check(argv)) {
3727 argc = PyTuple_Size(argv);
3728 getitem = PyTuple_GetItem;
3729 }
3730 else {
3731 PyErr_SetString(PyExc_TypeError,
3732 "spawnvpe() arg 2 must be a tuple or list");
3733 goto fail_0;
3734 }
3735 if (!PyMapping_Check(env)) {
3736 PyErr_SetString(PyExc_TypeError,
3737 "spawnvpe() arg 3 must be a mapping object");
3738 goto fail_0;
3739 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003740
Victor Stinnerd6f85422010-05-05 23:33:33 +00003741 argvlist = PyMem_NEW(char *, argc+1);
3742 if (argvlist == NULL) {
3743 PyErr_NoMemory();
3744 goto fail_0;
3745 }
3746 for (i = 0; i < argc; i++) {
3747 if (!PyArg_Parse((*getitem)(argv, i),
3748 "et;spawnvpe() arg 2 must contain only strings",
3749 Py_FileSystemDefaultEncoding,
3750 &argvlist[i]))
3751 {
3752 lastarg = i;
3753 goto fail_1;
3754 }
3755 }
3756 lastarg = argc;
3757 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003758
Victor Stinnerd6f85422010-05-05 23:33:33 +00003759 i = PyMapping_Size(env);
3760 if (i < 0)
3761 goto fail_1;
3762 envlist = PyMem_NEW(char *, i + 1);
3763 if (envlist == NULL) {
3764 PyErr_NoMemory();
3765 goto fail_1;
3766 }
3767 envc = 0;
3768 keys = PyMapping_Keys(env);
3769 vals = PyMapping_Values(env);
3770 if (!keys || !vals)
3771 goto fail_2;
3772 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3773 PyErr_SetString(PyExc_TypeError,
3774 "spawnvpe(): env.keys() or env.values() is not a list");
3775 goto fail_2;
3776 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003777
Victor Stinnerd6f85422010-05-05 23:33:33 +00003778 for (pos = 0; pos < i; pos++) {
3779 char *p, *k, *v;
3780 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003781
Victor Stinnerd6f85422010-05-05 23:33:33 +00003782 key = PyList_GetItem(keys, pos);
3783 val = PyList_GetItem(vals, pos);
3784 if (!key || !val)
3785 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786
Victor Stinnerd6f85422010-05-05 23:33:33 +00003787 if (!PyArg_Parse(
3788 key,
3789 "s;spawnvpe() arg 3 contains a non-string key",
3790 &k) ||
3791 !PyArg_Parse(
3792 val,
3793 "s;spawnvpe() arg 3 contains a non-string value",
3794 &v))
3795 {
3796 goto fail_2;
3797 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003798 /* Search from index 1 because on Windows starting '=' is allowed for
3799 defining hidden environment variables. */
3800 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3801 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3802 goto fail_2;
3803 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003804 len = PyString_Size(key) + PyString_Size(val) + 2;
3805 p = PyMem_NEW(char, len);
3806 if (p == NULL) {
3807 PyErr_NoMemory();
3808 goto fail_2;
3809 }
3810 PyOS_snprintf(p, len, "%s=%s", k, v);
3811 envlist[envc++] = p;
3812 }
3813 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003814
Victor Stinnerd6f85422010-05-05 23:33:33 +00003815 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003816#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003817 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003818#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003819 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003820#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003821 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003822
Victor Stinnerd6f85422010-05-05 23:33:33 +00003823 if (spawnval == -1)
3824 (void) posix_error();
3825 else
3826 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003827
3828 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003829 while (--envc >= 0)
3830 PyMem_DEL(envlist[envc]);
3831 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003832 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003833 free_string_array(argvlist, lastarg);
3834 Py_XDECREF(vals);
3835 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003836 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003837 PyMem_Free(path);
3838 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003839}
3840#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003841#endif /* HAVE_SPAWNV */
3842
3843
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003844#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003845PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003846"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003847Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3848\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003849Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003850
3851static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003852posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003853{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003854 pid_t pid;
3855 int result = 0;
3856 _PyImport_AcquireLock();
3857 pid = fork1();
3858 if (pid == 0) {
3859 /* child: this clobbers and resets the import lock. */
3860 PyOS_AfterFork();
3861 } else {
3862 /* parent: release the import lock. */
3863 result = _PyImport_ReleaseLock();
3864 }
3865 if (pid == -1)
3866 return posix_error();
3867 if (result < 0) {
3868 /* Don't clobber the OSError if the fork failed. */
3869 PyErr_SetString(PyExc_RuntimeError,
3870 "not holding the import lock");
3871 return NULL;
3872 }
3873 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003874}
3875#endif
3876
3877
Guido van Rossumad0ee831995-03-01 10:34:45 +00003878#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003880"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003881Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003882Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883
Barry Warsaw53699e91996-12-10 23:23:01 +00003884static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003885posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003886{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003887 pid_t pid;
3888 int result = 0;
3889 _PyImport_AcquireLock();
3890 pid = fork();
3891 if (pid == 0) {
3892 /* child: this clobbers and resets the import lock. */
3893 PyOS_AfterFork();
3894 } else {
3895 /* parent: release the import lock. */
3896 result = _PyImport_ReleaseLock();
3897 }
3898 if (pid == -1)
3899 return posix_error();
3900 if (result < 0) {
3901 /* Don't clobber the OSError if the fork failed. */
3902 PyErr_SetString(PyExc_RuntimeError,
3903 "not holding the import lock");
3904 return NULL;
3905 }
3906 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003907}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003908#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003909
Neal Norwitzb59798b2003-03-21 01:43:31 +00003910/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003911/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3912#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003913#define DEV_PTY_FILE "/dev/ptc"
3914#define HAVE_DEV_PTMX
3915#else
3916#define DEV_PTY_FILE "/dev/ptmx"
3917#endif
3918
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003919#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003920#ifdef HAVE_PTY_H
3921#include <pty.h>
3922#else
3923#ifdef HAVE_LIBUTIL_H
3924#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003925#else
3926#ifdef HAVE_UTIL_H
3927#include <util.h>
3928#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003929#endif /* HAVE_LIBUTIL_H */
3930#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003931#ifdef HAVE_STROPTS_H
3932#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003933#endif
3934#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003935
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003936#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003937PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003938"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003939Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003940
3941static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003942posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003943{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003944 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003945#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003946 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003947#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003948#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003949 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003950#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003951 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003952#endif
3953#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003954
Thomas Wouters70c21a12000-07-14 14:28:33 +00003955#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003956 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3957 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003958#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003959 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3960 if (slave_name == NULL)
3961 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003962
Victor Stinnerd6f85422010-05-05 23:33:33 +00003963 slave_fd = open(slave_name, O_RDWR);
3964 if (slave_fd < 0)
3965 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003966#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003967 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3968 if (master_fd < 0)
3969 return posix_error();
3970 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3971 /* change permission of slave */
3972 if (grantpt(master_fd) < 0) {
3973 PyOS_setsig(SIGCHLD, sig_saved);
3974 return posix_error();
3975 }
3976 /* unlock slave */
3977 if (unlockpt(master_fd) < 0) {
3978 PyOS_setsig(SIGCHLD, sig_saved);
3979 return posix_error();
3980 }
3981 PyOS_setsig(SIGCHLD, sig_saved);
3982 slave_name = ptsname(master_fd); /* get name of slave */
3983 if (slave_name == NULL)
3984 return posix_error();
3985 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3986 if (slave_fd < 0)
3987 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003988#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003989 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3990 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003991#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003992 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003993#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003994#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003995#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003996
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003998
Fred Drake8cef4cf2000-06-28 16:40:38 +00003999}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004000#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004001
4002#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004004"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004005Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4006Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004008
4009static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004010posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004011{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004012 int master_fd = -1, result = 0;
4013 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004014
Victor Stinnerd6f85422010-05-05 23:33:33 +00004015 _PyImport_AcquireLock();
4016 pid = forkpty(&master_fd, NULL, NULL, NULL);
4017 if (pid == 0) {
4018 /* child: this clobbers and resets the import lock. */
4019 PyOS_AfterFork();
4020 } else {
4021 /* parent: release the import lock. */
4022 result = _PyImport_ReleaseLock();
4023 }
4024 if (pid == -1)
4025 return posix_error();
4026 if (result < 0) {
4027 /* Don't clobber the OSError if the fork failed. */
4028 PyErr_SetString(PyExc_RuntimeError,
4029 "not holding the import lock");
4030 return NULL;
4031 }
4032 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004033}
4034#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004035
Guido van Rossumad0ee831995-03-01 10:34:45 +00004036#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004037PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004038"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004040
Barry Warsaw53699e91996-12-10 23:23:01 +00004041static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004042posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004043{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004044 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004045}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004046#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Guido van Rossumad0ee831995-03-01 10:34:45 +00004049#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004050PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004051"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Barry Warsaw53699e91996-12-10 23:23:01 +00004054static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004055posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004056{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004057 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004058}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004059#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004061
Guido van Rossumad0ee831995-03-01 10:34:45 +00004062#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004063PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004064"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004065Return the current process's group 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_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004069{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004070 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004071}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004072#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004075PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004076"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004077Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004078
Barry Warsaw53699e91996-12-10 23:23:01 +00004079static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004080posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004081{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004082 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004083}
4084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004085
Fred Drakec9680921999-12-13 16:37:25 +00004086#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004088"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004089Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004090
4091static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004092posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004093{
4094 PyObject *result = NULL;
4095
Fred Drakec9680921999-12-13 16:37:25 +00004096#ifdef NGROUPS_MAX
4097#define MAX_GROUPS NGROUPS_MAX
4098#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004099 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004100#define MAX_GROUPS 64
4101#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004102 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004103
Victor Stinner59729ff2011-07-05 11:28:19 +02004104 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004105 * This is a helper variable to store the intermediate result when
4106 * that happens.
4107 *
4108 * To keep the code readable the OSX behaviour is unconditional,
4109 * according to the POSIX spec this should be safe on all unix-y
4110 * systems.
4111 */
4112 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004113 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004114
Ned Deily80743642013-08-01 21:19:09 -07004115#ifdef __APPLE__
4116 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4117 * there are more groups than can fit in grouplist. Therefore, on OS X
4118 * always first call getgroups with length 0 to get the actual number
4119 * of groups.
4120 */
4121 n = getgroups(0, NULL);
4122 if (n < 0) {
4123 return posix_error();
4124 } else if (n <= MAX_GROUPS) {
4125 /* groups will fit in existing array */
4126 alt_grouplist = grouplist;
4127 } else {
4128 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4129 if (alt_grouplist == NULL) {
4130 errno = EINVAL;
4131 return posix_error();
4132 }
4133 }
4134
4135 n = getgroups(n, alt_grouplist);
4136 if (n == -1) {
4137 if (alt_grouplist != grouplist) {
4138 PyMem_Free(alt_grouplist);
4139 }
4140 return posix_error();
4141 }
4142#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004143 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004144 if (n < 0) {
4145 if (errno == EINVAL) {
4146 n = getgroups(0, NULL);
4147 if (n == -1) {
4148 return posix_error();
4149 }
4150 if (n == 0) {
4151 /* Avoid malloc(0) */
4152 alt_grouplist = grouplist;
4153 } else {
4154 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4155 if (alt_grouplist == NULL) {
4156 errno = EINVAL;
4157 return posix_error();
4158 }
4159 n = getgroups(n, alt_grouplist);
4160 if (n == -1) {
4161 PyMem_Free(alt_grouplist);
4162 return posix_error();
4163 }
4164 }
4165 } else {
4166 return posix_error();
4167 }
4168 }
Ned Deily80743642013-08-01 21:19:09 -07004169#endif
4170
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004171 result = PyList_New(n);
4172 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004173 int i;
4174 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004175 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004176 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004177 Py_DECREF(result);
4178 result = NULL;
4179 break;
Fred Drakec9680921999-12-13 16:37:25 +00004180 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004181 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004182 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004183 }
4184
4185 if (alt_grouplist != grouplist) {
4186 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004187 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004188
Fred Drakec9680921999-12-13 16:37:25 +00004189 return result;
4190}
4191#endif
4192
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004193#ifdef HAVE_INITGROUPS
4194PyDoc_STRVAR(posix_initgroups__doc__,
4195"initgroups(username, gid) -> None\n\n\
4196Call the system initgroups() to initialize the group access list with all of\n\
4197the groups of which the specified username is a member, plus the specified\n\
4198group id.");
4199
4200static PyObject *
4201posix_initgroups(PyObject *self, PyObject *args)
4202{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004203 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004204#ifdef __APPLE__
4205 int gid;
4206#else
4207 gid_t gid;
4208#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004209
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004210#ifdef __APPLE__
4211 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4212 &gid))
4213#else
4214 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4215 _Py_Gid_Converter, &gid))
4216#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004217 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004218
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004219 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004220 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004221
Victor Stinnerd6f85422010-05-05 23:33:33 +00004222 Py_INCREF(Py_None);
4223 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004224}
4225#endif
4226
Martin v. Löwis606edc12002-06-13 21:09:11 +00004227#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004228PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004229"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004230Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004231
4232static PyObject *
4233posix_getpgid(PyObject *self, PyObject *args)
4234{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004235 pid_t pid, pgid;
4236 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4237 return NULL;
4238 pgid = getpgid(pid);
4239 if (pgid < 0)
4240 return posix_error();
4241 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004242}
4243#endif /* HAVE_GETPGID */
4244
4245
Guido van Rossumb6775db1994-08-01 11:34:53 +00004246#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004247PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004248"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004249Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004250
Barry Warsaw53699e91996-12-10 23:23:01 +00004251static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004252posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004253{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004254#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004255 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004256#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004257 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004258#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004259}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Guido van Rossumb6775db1994-08-01 11:34:53 +00004263#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004264PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004265"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004266Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004269posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004270{
Guido van Rossum64933891994-10-20 21:56:42 +00004271#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004272 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004273#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004274 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004275#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004276 return posix_error();
4277 Py_INCREF(Py_None);
4278 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004279}
4280
Guido van Rossumb6775db1994-08-01 11:34:53 +00004281#endif /* HAVE_SETPGRP */
4282
Guido van Rossumad0ee831995-03-01 10:34:45 +00004283#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004284PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004285"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004286Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004287
Barry Warsaw53699e91996-12-10 23:23:01 +00004288static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004289posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004290{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004291 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004292}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004293#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Fred Drake12c6e2d1999-12-14 21:25:03 +00004296#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004298"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004300
4301static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004302posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004303{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004304 PyObject *result = NULL;
4305 char *name;
4306 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004307
Victor Stinnerd6f85422010-05-05 23:33:33 +00004308 errno = 0;
4309 name = getlogin();
4310 if (name == NULL) {
4311 if (errno)
4312 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004313 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004314 PyErr_SetString(PyExc_OSError,
4315 "unable to determine login name");
4316 }
4317 else
4318 result = PyString_FromString(name);
4319 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004320
Fred Drake12c6e2d1999-12-14 21:25:03 +00004321 return result;
4322}
4323#endif
4324
Guido van Rossumad0ee831995-03-01 10:34:45 +00004325#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004327"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004328Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004329
Barry Warsaw53699e91996-12-10 23:23:01 +00004330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004331posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004332{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004333 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004334}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004335#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004337
Guido van Rossumad0ee831995-03-01 10:34:45 +00004338#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004339PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004340"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004341Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004342
Barry Warsaw53699e91996-12-10 23:23:01 +00004343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004344posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004345{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004346 pid_t pid;
4347 int sig;
4348 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4349 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004350#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004351 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4352 APIRET rc;
4353 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004354 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004355
4356 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4357 APIRET rc;
4358 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004359 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004360
4361 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004362 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004363#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004364 if (kill(pid, sig) == -1)
4365 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004366#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004367 Py_INCREF(Py_None);
4368 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004369}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004370#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004371
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004372#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004373PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004374"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004375Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004376
4377static PyObject *
4378posix_killpg(PyObject *self, PyObject *args)
4379{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004380 int sig;
4381 pid_t pgid;
4382 /* XXX some man pages make the `pgid` parameter an int, others
4383 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4384 take the same type. Moreover, pid_t is always at least as wide as
4385 int (else compilation of this module fails), which is safe. */
4386 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4387 return NULL;
4388 if (killpg(pgid, sig) == -1)
4389 return posix_error();
4390 Py_INCREF(Py_None);
4391 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004392}
4393#endif
4394
Brian Curtine5aa8862010-04-02 23:26:06 +00004395#ifdef MS_WINDOWS
4396PyDoc_STRVAR(win32_kill__doc__,
4397"kill(pid, sig)\n\n\
4398Kill a process with a signal.");
4399
4400static PyObject *
4401win32_kill(PyObject *self, PyObject *args)
4402{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004403 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004404 DWORD pid, sig, err;
4405 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004406
Victor Stinnerd6f85422010-05-05 23:33:33 +00004407 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4408 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004409
Victor Stinnerd6f85422010-05-05 23:33:33 +00004410 /* Console processes which share a common console can be sent CTRL+C or
4411 CTRL+BREAK events, provided they handle said events. */
4412 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4413 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4414 err = GetLastError();
4415 return PyErr_SetFromWindowsErr(err);
4416 }
4417 else
4418 Py_RETURN_NONE;
4419 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004420
Victor Stinnerd6f85422010-05-05 23:33:33 +00004421 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4422 attempt to open and terminate the process. */
4423 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4424 if (handle == NULL) {
4425 err = GetLastError();
4426 return PyErr_SetFromWindowsErr(err);
4427 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004428
Victor Stinnerd6f85422010-05-05 23:33:33 +00004429 if (TerminateProcess(handle, sig) == 0) {
4430 err = GetLastError();
4431 result = PyErr_SetFromWindowsErr(err);
4432 } else {
4433 Py_INCREF(Py_None);
4434 result = Py_None;
4435 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004436
Victor Stinnerd6f85422010-05-05 23:33:33 +00004437 CloseHandle(handle);
4438 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004439}
Brian Curtincaea7e82011-06-08 19:29:53 -05004440
Brian Curtin5446f082011-06-09 10:00:42 -05004441PyDoc_STRVAR(posix__isdir__doc__,
4442"Return true if the pathname refers to an existing directory.");
4443
Brian Curtincaea7e82011-06-08 19:29:53 -05004444static PyObject *
4445posix__isdir(PyObject *self, PyObject *args)
4446{
Brian Curtincaea7e82011-06-08 19:29:53 -05004447 char *path;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004448 Py_UNICODE *wpath;
Brian Curtincaea7e82011-06-08 19:29:53 -05004449 DWORD attributes;
4450
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004451 if (PyArg_ParseTuple(args, "u|:_isdir", &wpath)) {
Brian Curtincaea7e82011-06-08 19:29:53 -05004452 attributes = GetFileAttributesW(wpath);
4453 if (attributes == INVALID_FILE_ATTRIBUTES)
4454 Py_RETURN_FALSE;
4455 goto check;
4456 }
4457 /* Drop the argument parsing error as narrow strings
4458 are also valid. */
4459 PyErr_Clear();
4460
4461 if (!PyArg_ParseTuple(args, "et:_isdir",
4462 Py_FileSystemDefaultEncoding, &path))
4463 return NULL;
4464
4465 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004466 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004467 if (attributes == INVALID_FILE_ATTRIBUTES)
4468 Py_RETURN_FALSE;
4469
4470check:
4471 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4472 Py_RETURN_TRUE;
4473 else
4474 Py_RETURN_FALSE;
4475}
Brian Curtine5aa8862010-04-02 23:26:06 +00004476#endif /* MS_WINDOWS */
4477
Guido van Rossumc0125471996-06-28 18:55:32 +00004478#ifdef HAVE_PLOCK
4479
4480#ifdef HAVE_SYS_LOCK_H
4481#include <sys/lock.h>
4482#endif
4483
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004484PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004485"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004486Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004487
Barry Warsaw53699e91996-12-10 23:23:01 +00004488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004489posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004490{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004491 int op;
4492 if (!PyArg_ParseTuple(args, "i:plock", &op))
4493 return NULL;
4494 if (plock(op) == -1)
4495 return posix_error();
4496 Py_INCREF(Py_None);
4497 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004498}
4499#endif
4500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004502#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004503PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004504"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004505Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004506
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004507#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004508#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004509static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004510async_system(const char *command)
4511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004512 char errormsg[256], args[1024];
4513 RESULTCODES rcodes;
4514 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004515
Victor Stinnerd6f85422010-05-05 23:33:33 +00004516 char *shell = getenv("COMSPEC");
4517 if (!shell)
4518 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004519
Victor Stinnerd6f85422010-05-05 23:33:33 +00004520 /* avoid overflowing the argument buffer */
4521 if (strlen(shell) + 3 + strlen(command) >= 1024)
4522 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004523
Victor Stinnerd6f85422010-05-05 23:33:33 +00004524 args[0] = '\0';
4525 strcat(args, shell);
4526 strcat(args, "/c ");
4527 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004528
Victor Stinnerd6f85422010-05-05 23:33:33 +00004529 /* execute asynchronously, inheriting the environment */
4530 rc = DosExecPgm(errormsg,
4531 sizeof(errormsg),
4532 EXEC_ASYNC,
4533 args,
4534 NULL,
4535 &rcodes,
4536 shell);
4537 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004538}
4539
Guido van Rossumd48f2521997-12-05 22:19:34 +00004540static FILE *
4541popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004542{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004543 int oldfd, tgtfd;
4544 HFILE pipeh[2];
4545 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004546
Victor Stinnerd6f85422010-05-05 23:33:33 +00004547 /* mode determines which of stdin or stdout is reconnected to
4548 * the pipe to the child
4549 */
4550 if (strchr(mode, 'r') != NULL) {
4551 tgt_fd = 1; /* stdout */
4552 } else if (strchr(mode, 'w')) {
4553 tgt_fd = 0; /* stdin */
4554 } else {
4555 *err = ERROR_INVALID_ACCESS;
4556 return NULL;
4557 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004558
Victor Stinnerd6f85422010-05-05 23:33:33 +00004559 /* setup the pipe */
4560 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4561 *err = rc;
4562 return NULL;
4563 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004564
Victor Stinnerd6f85422010-05-05 23:33:33 +00004565 /* prevent other threads accessing stdio */
4566 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004567
Victor Stinnerd6f85422010-05-05 23:33:33 +00004568 /* reconnect stdio and execute child */
4569 oldfd = dup(tgtfd);
4570 close(tgtfd);
4571 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4572 DosClose(pipeh[tgtfd]);
4573 rc = async_system(command);
4574 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004575
Victor Stinnerd6f85422010-05-05 23:33:33 +00004576 /* restore stdio */
4577 dup2(oldfd, tgtfd);
4578 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004579
Victor Stinnerd6f85422010-05-05 23:33:33 +00004580 /* allow other threads access to stdio */
4581 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004582
Victor Stinnerd6f85422010-05-05 23:33:33 +00004583 /* if execution of child was successful return file stream */
4584 if (rc == NO_ERROR)
4585 return fdopen(pipeh[1 - tgtfd], mode);
4586 else {
4587 DosClose(pipeh[1 - tgtfd]);
4588 *err = rc;
4589 return NULL;
4590 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004591}
4592
4593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004594posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004595{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004596 char *name;
4597 char *mode = "r";
4598 int err, bufsize = -1;
4599 FILE *fp;
4600 PyObject *f;
4601 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4602 return NULL;
4603 Py_BEGIN_ALLOW_THREADS
4604 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4605 Py_END_ALLOW_THREADS
4606 if (fp == NULL)
4607 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004608
Victor Stinnerd6f85422010-05-05 23:33:33 +00004609 f = PyFile_FromFile(fp, name, mode, fclose);
4610 if (f != NULL)
4611 PyFile_SetBufSize(f, bufsize);
4612 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004613}
4614
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615#elif defined(PYCC_GCC)
4616
4617/* standard posix version of popen() support */
4618static PyObject *
4619posix_popen(PyObject *self, PyObject *args)
4620{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004621 char *name;
4622 char *mode = "r";
4623 int bufsize = -1;
4624 FILE *fp;
4625 PyObject *f;
4626 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4627 return NULL;
4628 Py_BEGIN_ALLOW_THREADS
4629 fp = popen(name, mode);
4630 Py_END_ALLOW_THREADS
4631 if (fp == NULL)
4632 return posix_error();
4633 f = PyFile_FromFile(fp, name, mode, pclose);
4634 if (f != NULL)
4635 PyFile_SetBufSize(f, bufsize);
4636 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004637}
4638
4639/* fork() under OS/2 has lots'o'warts
4640 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4641 * most of this code is a ripoff of the win32 code, but using the
4642 * capabilities of EMX's C library routines
4643 */
4644
4645/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4646#define POPEN_1 1
4647#define POPEN_2 2
4648#define POPEN_3 3
4649#define POPEN_4 4
4650
4651static PyObject *_PyPopen(char *, int, int, int);
4652static int _PyPclose(FILE *file);
4653
4654/*
4655 * Internal dictionary mapping popen* file pointers to process handles,
4656 * for use when retrieving the process exit code. See _PyPclose() below
4657 * for more information on this dictionary's use.
4658 */
4659static PyObject *_PyPopenProcs = NULL;
4660
4661/* os2emx version of popen2()
4662 *
4663 * The result of this function is a pipe (file) connected to the
4664 * process's stdin, and a pipe connected to the process's stdout.
4665 */
4666
4667static PyObject *
4668os2emx_popen2(PyObject *self, PyObject *args)
4669{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004670 PyObject *f;
4671 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004672
Victor Stinnerd6f85422010-05-05 23:33:33 +00004673 char *cmdstring;
4674 char *mode = "t";
4675 int bufsize = -1;
4676 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4677 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004678
Victor Stinnerd6f85422010-05-05 23:33:33 +00004679 if (*mode == 't')
4680 tm = O_TEXT;
4681 else if (*mode != 'b') {
4682 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4683 return NULL;
4684 } else
4685 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004686
Victor Stinnerd6f85422010-05-05 23:33:33 +00004687 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004688
Victor Stinnerd6f85422010-05-05 23:33:33 +00004689 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004690}
4691
4692/*
4693 * Variation on os2emx.popen2
4694 *
4695 * The result of this function is 3 pipes - the process's stdin,
4696 * stdout and stderr
4697 */
4698
4699static PyObject *
4700os2emx_popen3(PyObject *self, PyObject *args)
4701{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004702 PyObject *f;
4703 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004704
Victor Stinnerd6f85422010-05-05 23:33:33 +00004705 char *cmdstring;
4706 char *mode = "t";
4707 int bufsize = -1;
4708 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4709 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004710
Victor Stinnerd6f85422010-05-05 23:33:33 +00004711 if (*mode == 't')
4712 tm = O_TEXT;
4713 else if (*mode != 'b') {
4714 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4715 return NULL;
4716 } else
4717 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004718
Victor Stinnerd6f85422010-05-05 23:33:33 +00004719 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004720
Victor Stinnerd6f85422010-05-05 23:33:33 +00004721 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004722}
4723
4724/*
4725 * Variation on os2emx.popen2
4726 *
Tim Peters11b23062003-04-23 02:39:17 +00004727 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004728 * and stdout+stderr combined as a single pipe.
4729 */
4730
4731static PyObject *
4732os2emx_popen4(PyObject *self, PyObject *args)
4733{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004734 PyObject *f;
4735 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004736
Victor Stinnerd6f85422010-05-05 23:33:33 +00004737 char *cmdstring;
4738 char *mode = "t";
4739 int bufsize = -1;
4740 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4741 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004742
Victor Stinnerd6f85422010-05-05 23:33:33 +00004743 if (*mode == 't')
4744 tm = O_TEXT;
4745 else if (*mode != 'b') {
4746 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4747 return NULL;
4748 } else
4749 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004750
Victor Stinnerd6f85422010-05-05 23:33:33 +00004751 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004752
Victor Stinnerd6f85422010-05-05 23:33:33 +00004753 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004754}
4755
4756/* a couple of structures for convenient handling of multiple
4757 * file handles and pipes
4758 */
4759struct file_ref
4760{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004761 int handle;
4762 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004763};
4764
4765struct pipe_ref
4766{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004767 int rd;
4768 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004769};
4770
4771/* The following code is derived from the win32 code */
4772
4773static PyObject *
4774_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4775{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004776 struct file_ref stdio[3];
4777 struct pipe_ref p_fd[3];
4778 FILE *p_s[3];
4779 int file_count, i, pipe_err;
4780 pid_t pipe_pid;
4781 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4782 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004783
Victor Stinnerd6f85422010-05-05 23:33:33 +00004784 /* file modes for subsequent fdopen's on pipe handles */
4785 if (mode == O_TEXT)
4786 {
4787 rd_mode = "rt";
4788 wr_mode = "wt";
4789 }
4790 else
4791 {
4792 rd_mode = "rb";
4793 wr_mode = "wb";
4794 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004795
Victor Stinnerd6f85422010-05-05 23:33:33 +00004796 /* prepare shell references */
4797 if ((shell = getenv("EMXSHELL")) == NULL)
4798 if ((shell = getenv("COMSPEC")) == NULL)
4799 {
4800 errno = ENOENT;
4801 return posix_error();
4802 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004803
Victor Stinnerd6f85422010-05-05 23:33:33 +00004804 sh_name = _getname(shell);
4805 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4806 opt = "/c";
4807 else
4808 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004809
Victor Stinnerd6f85422010-05-05 23:33:33 +00004810 /* save current stdio fds + their flags, and set not inheritable */
4811 i = pipe_err = 0;
4812 while (pipe_err >= 0 && i < 3)
4813 {
4814 pipe_err = stdio[i].handle = dup(i);
4815 stdio[i].flags = fcntl(i, F_GETFD, 0);
4816 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4817 i++;
4818 }
4819 if (pipe_err < 0)
4820 {
4821 /* didn't get them all saved - clean up and bail out */
4822 int saved_err = errno;
4823 while (i-- > 0)
4824 {
4825 close(stdio[i].handle);
4826 }
4827 errno = saved_err;
4828 return posix_error();
4829 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004830
Victor Stinnerd6f85422010-05-05 23:33:33 +00004831 /* create pipe ends */
4832 file_count = 2;
4833 if (n == POPEN_3)
4834 file_count = 3;
4835 i = pipe_err = 0;
4836 while ((pipe_err == 0) && (i < file_count))
4837 pipe_err = pipe((int *)&p_fd[i++]);
4838 if (pipe_err < 0)
4839 {
4840 /* didn't get them all made - clean up and bail out */
4841 while (i-- > 0)
4842 {
4843 close(p_fd[i].wr);
4844 close(p_fd[i].rd);
4845 }
4846 errno = EPIPE;
4847 return posix_error();
4848 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004849
Victor Stinnerd6f85422010-05-05 23:33:33 +00004850 /* change the actual standard IO streams over temporarily,
4851 * making the retained pipe ends non-inheritable
4852 */
4853 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004854
Victor Stinnerd6f85422010-05-05 23:33:33 +00004855 /* - stdin */
4856 if (dup2(p_fd[0].rd, 0) == 0)
4857 {
4858 close(p_fd[0].rd);
4859 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4860 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4861 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4862 {
4863 close(p_fd[0].wr);
4864 pipe_err = -1;
4865 }
4866 }
4867 else
4868 {
4869 pipe_err = -1;
4870 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004871
Victor Stinnerd6f85422010-05-05 23:33:33 +00004872 /* - stdout */
4873 if (pipe_err == 0)
4874 {
4875 if (dup2(p_fd[1].wr, 1) == 1)
4876 {
4877 close(p_fd[1].wr);
4878 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4879 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4880 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4881 {
4882 close(p_fd[1].rd);
4883 pipe_err = -1;
4884 }
4885 }
4886 else
4887 {
4888 pipe_err = -1;
4889 }
4890 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004891
Victor Stinnerd6f85422010-05-05 23:33:33 +00004892 /* - stderr, as required */
4893 if (pipe_err == 0)
4894 switch (n)
4895 {
4896 case POPEN_3:
4897 {
4898 if (dup2(p_fd[2].wr, 2) == 2)
4899 {
4900 close(p_fd[2].wr);
4901 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4902 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4903 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4904 {
4905 close(p_fd[2].rd);
4906 pipe_err = -1;
4907 }
4908 }
4909 else
4910 {
4911 pipe_err = -1;
4912 }
4913 break;
4914 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004915
Victor Stinnerd6f85422010-05-05 23:33:33 +00004916 case POPEN_4:
4917 {
4918 if (dup2(1, 2) != 2)
4919 {
4920 pipe_err = -1;
4921 }
4922 break;
4923 }
4924 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004925
Victor Stinnerd6f85422010-05-05 23:33:33 +00004926 /* spawn the child process */
4927 if (pipe_err == 0)
4928 {
4929 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4930 if (pipe_pid == -1)
4931 {
4932 pipe_err = -1;
4933 }
4934 else
4935 {
4936 /* save the PID into the FILE structure
4937 * NOTE: this implementation doesn't actually
4938 * take advantage of this, but do it for
4939 * completeness - AIM Apr01
4940 */
4941 for (i = 0; i < file_count; i++)
4942 p_s[i]->_pid = pipe_pid;
4943 }
4944 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004945
Victor Stinnerd6f85422010-05-05 23:33:33 +00004946 /* reset standard IO to normal */
4947 for (i = 0; i < 3; i++)
4948 {
4949 dup2(stdio[i].handle, i);
4950 fcntl(i, F_SETFD, stdio[i].flags);
4951 close(stdio[i].handle);
4952 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004953
Victor Stinnerd6f85422010-05-05 23:33:33 +00004954 /* if any remnant problems, clean up and bail out */
4955 if (pipe_err < 0)
4956 {
4957 for (i = 0; i < 3; i++)
4958 {
4959 close(p_fd[i].rd);
4960 close(p_fd[i].wr);
4961 }
4962 errno = EPIPE;
4963 return posix_error_with_filename(cmdstring);
4964 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004965
Victor Stinnerd6f85422010-05-05 23:33:33 +00004966 /* build tuple of file objects to return */
4967 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4968 PyFile_SetBufSize(p_f[0], bufsize);
4969 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4970 PyFile_SetBufSize(p_f[1], bufsize);
4971 if (n == POPEN_3)
4972 {
4973 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4974 PyFile_SetBufSize(p_f[0], bufsize);
4975 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4976 }
4977 else
4978 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004979
Victor Stinnerd6f85422010-05-05 23:33:33 +00004980 /*
4981 * Insert the files we've created into the process dictionary
4982 * all referencing the list with the process handle and the
4983 * initial number of files (see description below in _PyPclose).
4984 * Since if _PyPclose later tried to wait on a process when all
4985 * handles weren't closed, it could create a deadlock with the
4986 * child, we spend some energy here to try to ensure that we
4987 * either insert all file handles into the dictionary or none
4988 * at all. It's a little clumsy with the various popen modes
4989 * and variable number of files involved.
4990 */
4991 if (!_PyPopenProcs)
4992 {
4993 _PyPopenProcs = PyDict_New();
4994 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004995
Victor Stinnerd6f85422010-05-05 23:33:33 +00004996 if (_PyPopenProcs)
4997 {
4998 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4999 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005000
Victor Stinnerd6f85422010-05-05 23:33:33 +00005001 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5002 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005003
Victor Stinnerd6f85422010-05-05 23:33:33 +00005004 procObj = PyList_New(2);
5005 pidObj = PyLong_FromPid(pipe_pid);
5006 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005007
Victor Stinnerd6f85422010-05-05 23:33:33 +00005008 if (procObj && pidObj && intObj)
5009 {
5010 PyList_SetItem(procObj, 0, pidObj);
5011 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005012
Victor Stinnerd6f85422010-05-05 23:33:33 +00005013 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
5014 if (fileObj[0])
5015 {
5016 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5017 fileObj[0],
5018 procObj);
5019 }
5020 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5021 if (fileObj[1])
5022 {
5023 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5024 fileObj[1],
5025 procObj);
5026 }
5027 if (file_count >= 3)
5028 {
5029 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5030 if (fileObj[2])
5031 {
5032 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5033 fileObj[2],
5034 procObj);
5035 }
5036 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005037
Victor Stinnerd6f85422010-05-05 23:33:33 +00005038 if (ins_rc[0] < 0 || !fileObj[0] ||
5039 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5040 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5041 {
5042 /* Something failed - remove any dictionary
5043 * entries that did make it.
5044 */
5045 if (!ins_rc[0] && fileObj[0])
5046 {
5047 PyDict_DelItem(_PyPopenProcs,
5048 fileObj[0]);
5049 }
5050 if (!ins_rc[1] && fileObj[1])
5051 {
5052 PyDict_DelItem(_PyPopenProcs,
5053 fileObj[1]);
5054 }
5055 if (!ins_rc[2] && fileObj[2])
5056 {
5057 PyDict_DelItem(_PyPopenProcs,
5058 fileObj[2]);
5059 }
5060 }
5061 }
Tim Peters11b23062003-04-23 02:39:17 +00005062
Victor Stinnerd6f85422010-05-05 23:33:33 +00005063 /*
5064 * Clean up our localized references for the dictionary keys
5065 * and value since PyDict_SetItem will Py_INCREF any copies
5066 * that got placed in the dictionary.
5067 */
5068 Py_XDECREF(procObj);
5069 Py_XDECREF(fileObj[0]);
5070 Py_XDECREF(fileObj[1]);
5071 Py_XDECREF(fileObj[2]);
5072 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005073
Victor Stinnerd6f85422010-05-05 23:33:33 +00005074 /* Child is launched. */
5075 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005076}
5077
5078/*
5079 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5080 * exit code for the child process and return as a result of the close.
5081 *
5082 * This function uses the _PyPopenProcs dictionary in order to map the
5083 * input file pointer to information about the process that was
5084 * originally created by the popen* call that created the file pointer.
5085 * The dictionary uses the file pointer as a key (with one entry
5086 * inserted for each file returned by the original popen* call) and a
5087 * single list object as the value for all files from a single call.
5088 * The list object contains the Win32 process handle at [0], and a file
5089 * count at [1], which is initialized to the total number of file
5090 * handles using that list.
5091 *
5092 * This function closes whichever handle it is passed, and decrements
5093 * the file count in the dictionary for the process handle pointed to
5094 * by this file. On the last close (when the file count reaches zero),
5095 * this function will wait for the child process and then return its
5096 * exit code as the result of the close() operation. This permits the
5097 * files to be closed in any order - it is always the close() of the
5098 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005099 *
5100 * NOTE: This function is currently called with the GIL released.
5101 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005102 */
5103
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005104static int _PyPclose(FILE *file)
5105{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005106 int result;
5107 int exit_code;
5108 pid_t pipe_pid;
5109 PyObject *procObj, *pidObj, *intObj, *fileObj;
5110 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005111#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005112 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005113#endif
5114
Victor Stinnerd6f85422010-05-05 23:33:33 +00005115 /* Close the file handle first, to ensure it can't block the
5116 * child from exiting if it's the last handle.
5117 */
5118 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005119
5120#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005121 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005122#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005123 if (_PyPopenProcs)
5124 {
5125 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5126 (procObj = PyDict_GetItem(_PyPopenProcs,
5127 fileObj)) != NULL &&
5128 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5129 (intObj = PyList_GetItem(procObj,1)) != NULL)
5130 {
5131 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5132 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005133
Victor Stinnerd6f85422010-05-05 23:33:33 +00005134 if (file_count > 1)
5135 {
5136 /* Still other files referencing process */
5137 file_count--;
5138 PyList_SetItem(procObj,1,
5139 PyInt_FromLong((long) file_count));
5140 }
5141 else
5142 {
5143 /* Last file for this process */
5144 if (result != EOF &&
5145 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5146 {
5147 /* extract exit status */
5148 if (WIFEXITED(exit_code))
5149 {
5150 result = WEXITSTATUS(exit_code);
5151 }
5152 else
5153 {
5154 errno = EPIPE;
5155 result = -1;
5156 }
5157 }
5158 else
5159 {
5160 /* Indicate failure - this will cause the file object
5161 * to raise an I/O error and translate the last
5162 * error code from errno. We do have a problem with
5163 * last errors that overlap the normal errno table,
5164 * but that's a consistent problem with the file object.
5165 */
5166 result = -1;
5167 }
5168 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005169
Victor Stinnerd6f85422010-05-05 23:33:33 +00005170 /* Remove this file pointer from dictionary */
5171 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005172
Victor Stinnerd6f85422010-05-05 23:33:33 +00005173 if (PyDict_Size(_PyPopenProcs) == 0)
5174 {
5175 Py_DECREF(_PyPopenProcs);
5176 _PyPopenProcs = NULL;
5177 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005178
Victor Stinnerd6f85422010-05-05 23:33:33 +00005179 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005180
Victor Stinnerd6f85422010-05-05 23:33:33 +00005181 Py_XDECREF(fileObj);
5182 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005183
5184#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005185 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005186#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005187 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005188}
5189
5190#endif /* PYCC_??? */
5191
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005192#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005193
5194/*
5195 * Portable 'popen' replacement for Win32.
5196 *
5197 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5198 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005199 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005200 */
5201
5202#include <malloc.h>
5203#include <io.h>
5204#include <fcntl.h>
5205
5206/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5207#define POPEN_1 1
5208#define POPEN_2 2
5209#define POPEN_3 3
5210#define POPEN_4 4
5211
5212static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005213static int _PyPclose(FILE *file);
5214
5215/*
5216 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005217 * for use when retrieving the process exit code. See _PyPclose() below
5218 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005219 */
5220static PyObject *_PyPopenProcs = NULL;
5221
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005222
5223/* popen that works from a GUI.
5224 *
5225 * The result of this function is a pipe (file) connected to the
5226 * processes stdin or stdout, depending on the requested mode.
5227 */
5228
5229static PyObject *
5230posix_popen(PyObject *self, PyObject *args)
5231{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005232 PyObject *f;
5233 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005234
Victor Stinnerd6f85422010-05-05 23:33:33 +00005235 char *cmdstring;
5236 char *mode = "r";
5237 int bufsize = -1;
5238 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5239 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005240
Victor Stinnerd6f85422010-05-05 23:33:33 +00005241 if (*mode == 'r')
5242 tm = _O_RDONLY;
5243 else if (*mode != 'w') {
5244 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5245 return NULL;
5246 } else
5247 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005248
Victor Stinnerd6f85422010-05-05 23:33:33 +00005249 if (bufsize != -1) {
5250 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5251 return NULL;
5252 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005253
Victor Stinnerd6f85422010-05-05 23:33:33 +00005254 if (*(mode+1) == 't')
5255 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5256 else if (*(mode+1) == 'b')
5257 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5258 else
5259 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005260
Victor Stinnerd6f85422010-05-05 23:33:33 +00005261 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005262}
5263
5264/* Variation on win32pipe.popen
5265 *
5266 * The result of this function is a pipe (file) connected to the
5267 * process's stdin, and a pipe connected to the process's stdout.
5268 */
5269
5270static PyObject *
5271win32_popen2(PyObject *self, PyObject *args)
5272{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005273 PyObject *f;
5274 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005275
Victor Stinnerd6f85422010-05-05 23:33:33 +00005276 char *cmdstring;
5277 char *mode = "t";
5278 int bufsize = -1;
5279 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5280 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005281
Victor Stinnerd6f85422010-05-05 23:33:33 +00005282 if (*mode == 't')
5283 tm = _O_TEXT;
5284 else if (*mode != 'b') {
5285 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5286 return NULL;
5287 } else
5288 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005289
Victor Stinnerd6f85422010-05-05 23:33:33 +00005290 if (bufsize != -1) {
5291 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5292 return NULL;
5293 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005294
Victor Stinnerd6f85422010-05-05 23:33:33 +00005295 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005296
Victor Stinnerd6f85422010-05-05 23:33:33 +00005297 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005298}
5299
5300/*
5301 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005302 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005303 * The result of this function is 3 pipes - the process's stdin,
5304 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005305 */
5306
5307static PyObject *
5308win32_popen3(PyObject *self, PyObject *args)
5309{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005310 PyObject *f;
5311 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005312
Victor Stinnerd6f85422010-05-05 23:33:33 +00005313 char *cmdstring;
5314 char *mode = "t";
5315 int bufsize = -1;
5316 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5317 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005318
Victor Stinnerd6f85422010-05-05 23:33:33 +00005319 if (*mode == 't')
5320 tm = _O_TEXT;
5321 else if (*mode != 'b') {
5322 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5323 return NULL;
5324 } else
5325 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005326
Victor Stinnerd6f85422010-05-05 23:33:33 +00005327 if (bufsize != -1) {
5328 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5329 return NULL;
5330 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005331
Victor Stinnerd6f85422010-05-05 23:33:33 +00005332 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005333
Victor Stinnerd6f85422010-05-05 23:33:33 +00005334 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005335}
5336
5337/*
5338 * Variation on win32pipe.popen
5339 *
Tim Peters5aa91602002-01-30 05:46:57 +00005340 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341 * and stdout+stderr combined as a single pipe.
5342 */
5343
5344static PyObject *
5345win32_popen4(PyObject *self, PyObject *args)
5346{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005347 PyObject *f;
5348 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005349
Victor Stinnerd6f85422010-05-05 23:33:33 +00005350 char *cmdstring;
5351 char *mode = "t";
5352 int bufsize = -1;
5353 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5354 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005355
Victor Stinnerd6f85422010-05-05 23:33:33 +00005356 if (*mode == 't')
5357 tm = _O_TEXT;
5358 else if (*mode != 'b') {
5359 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5360 return NULL;
5361 } else
5362 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005363
Victor Stinnerd6f85422010-05-05 23:33:33 +00005364 if (bufsize != -1) {
5365 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5366 return NULL;
5367 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005368
Victor Stinnerd6f85422010-05-05 23:33:33 +00005369 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005370
Victor Stinnerd6f85422010-05-05 23:33:33 +00005371 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005372}
5373
Mark Hammond08501372001-01-31 07:30:29 +00005374static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005375_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005376 HANDLE hStdin,
5377 HANDLE hStdout,
5378 HANDLE hStderr,
5379 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005380{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005381 PROCESS_INFORMATION piProcInfo;
5382 STARTUPINFO siStartInfo;
5383 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5384 char *s1,*s2, *s3 = " /c ";
5385 const char *szConsoleSpawn = "w9xpopen.exe";
5386 int i;
5387 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005388
Victor Stinnerd6f85422010-05-05 23:33:33 +00005389 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5390 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005391
Victor Stinnerd6f85422010-05-05 23:33:33 +00005392 s1 = (char *)alloca(i);
5393 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5394 /* x < i, so x fits into an integer */
5395 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005396
Victor Stinnerd6f85422010-05-05 23:33:33 +00005397 /* Explicitly check if we are using COMMAND.COM. If we are
5398 * then use the w9xpopen hack.
5399 */
5400 comshell = s1 + x;
5401 while (comshell >= s1 && *comshell != '\\')
5402 --comshell;
5403 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005404
Victor Stinnerd6f85422010-05-05 23:33:33 +00005405 if (GetVersion() < 0x80000000 &&
5406 _stricmp(comshell, "command.com") != 0) {
5407 /* NT/2000 and not using command.com. */
5408 x = i + strlen(s3) + strlen(cmdstring) + 1;
5409 s2 = (char *)alloca(x);
5410 ZeroMemory(s2, x);
5411 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5412 }
5413 else {
5414 /*
5415 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5416 * the workaround listed in KB: Q150956
5417 */
5418 char modulepath[_MAX_PATH];
5419 struct stat statinfo;
5420 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5421 for (x = i = 0; modulepath[i]; i++)
5422 if (modulepath[i] == SEP)
5423 x = i+1;
5424 modulepath[x] = '\0';
5425 /* Create the full-name to w9xpopen, so we can test it exists */
5426 strncat(modulepath,
5427 szConsoleSpawn,
5428 (sizeof(modulepath)/sizeof(modulepath[0]))
5429 -strlen(modulepath));
5430 if (stat(modulepath, &statinfo) != 0) {
5431 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5432 /* Eeek - file-not-found - possibly an embedding
5433 situation - see if we can locate it in sys.prefix
5434 */
5435 strncpy(modulepath,
5436 Py_GetExecPrefix(),
5437 mplen);
5438 modulepath[mplen-1] = '\0';
5439 if (modulepath[strlen(modulepath)-1] != '\\')
5440 strcat(modulepath, "\\");
5441 strncat(modulepath,
5442 szConsoleSpawn,
5443 mplen-strlen(modulepath));
5444 /* No where else to look - raise an easily identifiable
5445 error, rather than leaving Windows to report
5446 "file not found" - as the user is probably blissfully
5447 unaware this shim EXE is used, and it will confuse them.
5448 (well, it confused me for a while ;-)
5449 */
5450 if (stat(modulepath, &statinfo) != 0) {
5451 PyErr_Format(PyExc_RuntimeError,
5452 "Can not locate '%s' which is needed "
5453 "for popen to work with your shell "
5454 "or platform.",
5455 szConsoleSpawn);
5456 return FALSE;
5457 }
5458 }
5459 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5460 strlen(modulepath) +
5461 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005462
Victor Stinnerd6f85422010-05-05 23:33:33 +00005463 s2 = (char *)alloca(x);
5464 ZeroMemory(s2, x);
5465 /* To maintain correct argument passing semantics,
5466 we pass the command-line as it stands, and allow
5467 quoting to be applied. w9xpopen.exe will then
5468 use its argv vector, and re-quote the necessary
5469 args for the ultimate child process.
5470 */
5471 PyOS_snprintf(
5472 s2, x,
5473 "\"%s\" %s%s%s",
5474 modulepath,
5475 s1,
5476 s3,
5477 cmdstring);
5478 /* Not passing CREATE_NEW_CONSOLE has been known to
5479 cause random failures on win9x. Specifically a
5480 dialog:
5481 "Your program accessed mem currently in use at xxx"
5482 and a hopeful warning about the stability of your
5483 system.
5484 Cost is Ctrl+C won't kill children, but anyone
5485 who cares can have a go!
5486 */
5487 dwProcessFlags |= CREATE_NEW_CONSOLE;
5488 }
5489 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005490
Victor Stinnerd6f85422010-05-05 23:33:33 +00005491 /* Could be an else here to try cmd.exe / command.com in the path
5492 Now we'll just error out.. */
5493 else {
5494 PyErr_SetString(PyExc_RuntimeError,
5495 "Cannot locate a COMSPEC environment variable to "
5496 "use as the shell");
5497 return FALSE;
5498 }
Tim Peters5aa91602002-01-30 05:46:57 +00005499
Victor Stinnerd6f85422010-05-05 23:33:33 +00005500 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5501 siStartInfo.cb = sizeof(STARTUPINFO);
5502 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5503 siStartInfo.hStdInput = hStdin;
5504 siStartInfo.hStdOutput = hStdout;
5505 siStartInfo.hStdError = hStderr;
5506 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005507
Victor Stinnerd6f85422010-05-05 23:33:33 +00005508 if (CreateProcess(NULL,
5509 s2,
5510 NULL,
5511 NULL,
5512 TRUE,
5513 dwProcessFlags,
5514 NULL,
5515 NULL,
5516 &siStartInfo,
5517 &piProcInfo) ) {
5518 /* Close the handles now so anyone waiting is woken. */
5519 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005520
Victor Stinnerd6f85422010-05-05 23:33:33 +00005521 /* Return process handle */
5522 *hProcess = piProcInfo.hProcess;
5523 return TRUE;
5524 }
5525 win32_error("CreateProcess", s2);
5526 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005527}
5528
5529/* The following code is based off of KB: Q190351 */
5530
5531static PyObject *
5532_PyPopen(char *cmdstring, int mode, int n)
5533{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005534 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5535 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5536 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005537
Victor Stinnerd6f85422010-05-05 23:33:33 +00005538 SECURITY_ATTRIBUTES saAttr;
5539 BOOL fSuccess;
5540 int fd1, fd2, fd3;
5541 FILE *f1, *f2, *f3;
5542 long file_count;
5543 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005544
Victor Stinnerd6f85422010-05-05 23:33:33 +00005545 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5546 saAttr.bInheritHandle = TRUE;
5547 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005548
Victor Stinnerd6f85422010-05-05 23:33:33 +00005549 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5550 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005551
Victor Stinnerd6f85422010-05-05 23:33:33 +00005552 /* Create new output read handle and the input write handle. Set
5553 * the inheritance properties to FALSE. Otherwise, the child inherits
5554 * these handles; resulting in non-closeable handles to the pipes
5555 * being created. */
5556 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5557 GetCurrentProcess(), &hChildStdinWrDup, 0,
5558 FALSE,
5559 DUPLICATE_SAME_ACCESS);
5560 if (!fSuccess)
5561 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005562
Victor Stinnerd6f85422010-05-05 23:33:33 +00005563 /* Close the inheritable version of ChildStdin
5564 that we're using. */
5565 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005566
Victor Stinnerd6f85422010-05-05 23:33:33 +00005567 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5568 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005569
Victor Stinnerd6f85422010-05-05 23:33:33 +00005570 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5571 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5572 FALSE, DUPLICATE_SAME_ACCESS);
5573 if (!fSuccess)
5574 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005575
Victor Stinnerd6f85422010-05-05 23:33:33 +00005576 /* Close the inheritable version of ChildStdout
5577 that we're using. */
5578 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005579
Victor Stinnerd6f85422010-05-05 23:33:33 +00005580 if (n != POPEN_4) {
5581 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5582 return win32_error("CreatePipe", NULL);
5583 fSuccess = DuplicateHandle(GetCurrentProcess(),
5584 hChildStderrRd,
5585 GetCurrentProcess(),
5586 &hChildStderrRdDup, 0,
5587 FALSE, DUPLICATE_SAME_ACCESS);
5588 if (!fSuccess)
5589 return win32_error("DuplicateHandle", NULL);
5590 /* Close the inheritable version of ChildStdErr that we're using. */
5591 CloseHandle(hChildStderrRd);
5592 }
Tim Peters5aa91602002-01-30 05:46:57 +00005593
Victor Stinnerd6f85422010-05-05 23:33:33 +00005594 switch (n) {
5595 case POPEN_1:
5596 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5597 case _O_WRONLY | _O_TEXT:
5598 /* Case for writing to child Stdin in text mode. */
5599 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5600 f1 = _fdopen(fd1, "w");
5601 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5602 PyFile_SetBufSize(f, 0);
5603 /* We don't care about these pipes anymore, so close them. */
5604 CloseHandle(hChildStdoutRdDup);
5605 CloseHandle(hChildStderrRdDup);
5606 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005607
Victor Stinnerd6f85422010-05-05 23:33:33 +00005608 case _O_RDONLY | _O_TEXT:
5609 /* Case for reading from child Stdout in text mode. */
5610 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5611 f1 = _fdopen(fd1, "r");
5612 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5613 PyFile_SetBufSize(f, 0);
5614 /* We don't care about these pipes anymore, so close them. */
5615 CloseHandle(hChildStdinWrDup);
5616 CloseHandle(hChildStderrRdDup);
5617 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005618
Victor Stinnerd6f85422010-05-05 23:33:33 +00005619 case _O_RDONLY | _O_BINARY:
5620 /* Case for readinig from child Stdout in binary mode. */
5621 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5622 f1 = _fdopen(fd1, "rb");
5623 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5624 PyFile_SetBufSize(f, 0);
5625 /* We don't care about these pipes anymore, so close them. */
5626 CloseHandle(hChildStdinWrDup);
5627 CloseHandle(hChildStderrRdDup);
5628 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005629
Victor Stinnerd6f85422010-05-05 23:33:33 +00005630 case _O_WRONLY | _O_BINARY:
5631 /* Case for writing to child Stdin in binary mode. */
5632 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5633 f1 = _fdopen(fd1, "wb");
5634 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5635 PyFile_SetBufSize(f, 0);
5636 /* We don't care about these pipes anymore, so close them. */
5637 CloseHandle(hChildStdoutRdDup);
5638 CloseHandle(hChildStderrRdDup);
5639 break;
5640 }
5641 file_count = 1;
5642 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005643
Victor Stinnerd6f85422010-05-05 23:33:33 +00005644 case POPEN_2:
5645 case POPEN_4:
5646 {
5647 char *m1, *m2;
5648 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005649
Victor Stinnerd6f85422010-05-05 23:33:33 +00005650 if (mode & _O_TEXT) {
5651 m1 = "r";
5652 m2 = "w";
5653 } else {
5654 m1 = "rb";
5655 m2 = "wb";
5656 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005657
Victor Stinnerd6f85422010-05-05 23:33:33 +00005658 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5659 f1 = _fdopen(fd1, m2);
5660 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5661 f2 = _fdopen(fd2, m1);
5662 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5663 PyFile_SetBufSize(p1, 0);
5664 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5665 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005666
Victor Stinnerd6f85422010-05-05 23:33:33 +00005667 if (n != 4)
5668 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005669
Victor Stinnerd6f85422010-05-05 23:33:33 +00005670 f = PyTuple_Pack(2,p1,p2);
5671 Py_XDECREF(p1);
5672 Py_XDECREF(p2);
5673 file_count = 2;
5674 break;
5675 }
Tim Peters5aa91602002-01-30 05:46:57 +00005676
Victor Stinnerd6f85422010-05-05 23:33:33 +00005677 case POPEN_3:
5678 {
5679 char *m1, *m2;
5680 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Victor Stinnerd6f85422010-05-05 23:33:33 +00005682 if (mode & _O_TEXT) {
5683 m1 = "r";
5684 m2 = "w";
5685 } else {
5686 m1 = "rb";
5687 m2 = "wb";
5688 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005689
Victor Stinnerd6f85422010-05-05 23:33:33 +00005690 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5691 f1 = _fdopen(fd1, m2);
5692 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5693 f2 = _fdopen(fd2, m1);
5694 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5695 f3 = _fdopen(fd3, m1);
5696 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5697 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5698 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5699 PyFile_SetBufSize(p1, 0);
5700 PyFile_SetBufSize(p2, 0);
5701 PyFile_SetBufSize(p3, 0);
5702 f = PyTuple_Pack(3,p1,p2,p3);
5703 Py_XDECREF(p1);
5704 Py_XDECREF(p2);
5705 Py_XDECREF(p3);
5706 file_count = 3;
5707 break;
5708 }
5709 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005710
Victor Stinnerd6f85422010-05-05 23:33:33 +00005711 if (n == POPEN_4) {
5712 if (!_PyPopenCreateProcess(cmdstring,
5713 hChildStdinRd,
5714 hChildStdoutWr,
5715 hChildStdoutWr,
5716 &hProcess))
5717 return NULL;
5718 }
5719 else {
5720 if (!_PyPopenCreateProcess(cmdstring,
5721 hChildStdinRd,
5722 hChildStdoutWr,
5723 hChildStderrWr,
5724 &hProcess))
5725 return NULL;
5726 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005727
Victor Stinnerd6f85422010-05-05 23:33:33 +00005728 /*
5729 * Insert the files we've created into the process dictionary
5730 * all referencing the list with the process handle and the
5731 * initial number of files (see description below in _PyPclose).
5732 * Since if _PyPclose later tried to wait on a process when all
5733 * handles weren't closed, it could create a deadlock with the
5734 * child, we spend some energy here to try to ensure that we
5735 * either insert all file handles into the dictionary or none
5736 * at all. It's a little clumsy with the various popen modes
5737 * and variable number of files involved.
5738 */
5739 if (!_PyPopenProcs) {
5740 _PyPopenProcs = PyDict_New();
5741 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005742
Victor Stinnerd6f85422010-05-05 23:33:33 +00005743 if (_PyPopenProcs) {
5744 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5745 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005746
Victor Stinnerd6f85422010-05-05 23:33:33 +00005747 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5748 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005749
Victor Stinnerd6f85422010-05-05 23:33:33 +00005750 procObj = PyList_New(2);
5751 hProcessObj = PyLong_FromVoidPtr(hProcess);
5752 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005753
Victor Stinnerd6f85422010-05-05 23:33:33 +00005754 if (procObj && hProcessObj && intObj) {
5755 PyList_SetItem(procObj,0,hProcessObj);
5756 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005757
Victor Stinnerd6f85422010-05-05 23:33:33 +00005758 fileObj[0] = PyLong_FromVoidPtr(f1);
5759 if (fileObj[0]) {
5760 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5761 fileObj[0],
5762 procObj);
5763 }
5764 if (file_count >= 2) {
5765 fileObj[1] = PyLong_FromVoidPtr(f2);
5766 if (fileObj[1]) {
5767 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5768 fileObj[1],
5769 procObj);
5770 }
5771 }
5772 if (file_count >= 3) {
5773 fileObj[2] = PyLong_FromVoidPtr(f3);
5774 if (fileObj[2]) {
5775 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5776 fileObj[2],
5777 procObj);
5778 }
5779 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005780
Victor Stinnerd6f85422010-05-05 23:33:33 +00005781 if (ins_rc[0] < 0 || !fileObj[0] ||
5782 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5783 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5784 /* Something failed - remove any dictionary
5785 * entries that did make it.
5786 */
5787 if (!ins_rc[0] && fileObj[0]) {
5788 PyDict_DelItem(_PyPopenProcs,
5789 fileObj[0]);
5790 }
5791 if (!ins_rc[1] && fileObj[1]) {
5792 PyDict_DelItem(_PyPopenProcs,
5793 fileObj[1]);
5794 }
5795 if (!ins_rc[2] && fileObj[2]) {
5796 PyDict_DelItem(_PyPopenProcs,
5797 fileObj[2]);
5798 }
5799 }
5800 }
Tim Peters5aa91602002-01-30 05:46:57 +00005801
Victor Stinnerd6f85422010-05-05 23:33:33 +00005802 /*
5803 * Clean up our localized references for the dictionary keys
5804 * and value since PyDict_SetItem will Py_INCREF any copies
5805 * that got placed in the dictionary.
5806 */
5807 Py_XDECREF(procObj);
5808 Py_XDECREF(fileObj[0]);
5809 Py_XDECREF(fileObj[1]);
5810 Py_XDECREF(fileObj[2]);
5811 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005812
Victor Stinnerd6f85422010-05-05 23:33:33 +00005813 /* Child is launched. Close the parents copy of those pipe
5814 * handles that only the child should have open. You need to
5815 * make sure that no handles to the write end of the output pipe
5816 * are maintained in this process or else the pipe will not close
5817 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005818
Victor Stinnerd6f85422010-05-05 23:33:33 +00005819 if (!CloseHandle(hChildStdinRd))
5820 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005821
Victor Stinnerd6f85422010-05-05 23:33:33 +00005822 if (!CloseHandle(hChildStdoutWr))
5823 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005824
Victor Stinnerd6f85422010-05-05 23:33:33 +00005825 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5826 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005827
Victor Stinnerd6f85422010-05-05 23:33:33 +00005828 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005829}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005830
5831/*
5832 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5833 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005834 *
5835 * This function uses the _PyPopenProcs dictionary in order to map the
5836 * input file pointer to information about the process that was
5837 * originally created by the popen* call that created the file pointer.
5838 * The dictionary uses the file pointer as a key (with one entry
5839 * inserted for each file returned by the original popen* call) and a
5840 * single list object as the value for all files from a single call.
5841 * The list object contains the Win32 process handle at [0], and a file
5842 * count at [1], which is initialized to the total number of file
5843 * handles using that list.
5844 *
5845 * This function closes whichever handle it is passed, and decrements
5846 * the file count in the dictionary for the process handle pointed to
5847 * by this file. On the last close (when the file count reaches zero),
5848 * this function will wait for the child process and then return its
5849 * exit code as the result of the close() operation. This permits the
5850 * files to be closed in any order - it is always the close() of the
5851 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005852 *
5853 * NOTE: This function is currently called with the GIL released.
5854 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005855 */
Tim Peters736aa322000-09-01 06:51:24 +00005856
Fredrik Lundh56055a42000-07-23 19:47:12 +00005857static int _PyPclose(FILE *file)
5858{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005859 int result;
5860 DWORD exit_code;
5861 HANDLE hProcess;
5862 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5863 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005864#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005865 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005866#endif
5867
Victor Stinnerd6f85422010-05-05 23:33:33 +00005868 /* Close the file handle first, to ensure it can't block the
5869 * child from exiting if it's the last handle.
5870 */
5871 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005872#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005873 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005874#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005875 if (_PyPopenProcs) {
5876 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5877 (procObj = PyDict_GetItem(_PyPopenProcs,
5878 fileObj)) != NULL &&
5879 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5880 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005881
Victor Stinnerd6f85422010-05-05 23:33:33 +00005882 hProcess = PyLong_AsVoidPtr(hProcessObj);
5883 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005884
Victor Stinnerd6f85422010-05-05 23:33:33 +00005885 if (file_count > 1) {
5886 /* Still other files referencing process */
5887 file_count--;
5888 PyList_SetItem(procObj,1,
5889 PyInt_FromLong(file_count));
5890 } else {
5891 /* Last file for this process */
5892 if (result != EOF &&
5893 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5894 GetExitCodeProcess(hProcess, &exit_code)) {
5895 /* Possible truncation here in 16-bit environments, but
5896 * real exit codes are just the lower byte in any event.
5897 */
5898 result = exit_code;
5899 } else {
5900 /* Indicate failure - this will cause the file object
5901 * to raise an I/O error and translate the last Win32
5902 * error code from errno. We do have a problem with
5903 * last errors that overlap the normal errno table,
5904 * but that's a consistent problem with the file object.
5905 */
5906 if (result != EOF) {
5907 /* If the error wasn't from the fclose(), then
5908 * set errno for the file object error handling.
5909 */
5910 errno = GetLastError();
5911 }
5912 result = -1;
5913 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005914
Victor Stinnerd6f85422010-05-05 23:33:33 +00005915 /* Free up the native handle at this point */
5916 CloseHandle(hProcess);
5917 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005918
Victor Stinnerd6f85422010-05-05 23:33:33 +00005919 /* Remove this file pointer from dictionary */
5920 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005921
Victor Stinnerd6f85422010-05-05 23:33:33 +00005922 if (PyDict_Size(_PyPopenProcs) == 0) {
5923 Py_DECREF(_PyPopenProcs);
5924 _PyPopenProcs = NULL;
5925 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005926
Victor Stinnerd6f85422010-05-05 23:33:33 +00005927 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005928
Victor Stinnerd6f85422010-05-05 23:33:33 +00005929 Py_XDECREF(fileObj);
5930 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005931
Tim Peters736aa322000-09-01 06:51:24 +00005932#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005933 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005934#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005935 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005936}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005937
5938#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005940posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005941{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005942 char *name;
5943 char *mode = "r";
5944 int bufsize = -1;
5945 FILE *fp;
5946 PyObject *f;
5947 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5948 return NULL;
5949 /* Strip mode of binary or text modifiers */
5950 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5951 mode = "r";
5952 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5953 mode = "w";
5954 Py_BEGIN_ALLOW_THREADS
5955 fp = popen(name, mode);
5956 Py_END_ALLOW_THREADS
5957 if (fp == NULL)
5958 return posix_error();
5959 f = PyFile_FromFile(fp, name, mode, pclose);
5960 if (f != NULL)
5961 PyFile_SetBufSize(f, bufsize);
5962 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005963}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005964
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005965#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005966#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005968
Guido van Rossumb6775db1994-08-01 11:34:53 +00005969#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005971"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972Set the current process's user id.");
5973
Barry Warsaw53699e91996-12-10 23:23:01 +00005974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005975posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005976{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005977 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005978 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005979 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005980 if (setuid(uid) < 0)
5981 return posix_error();
5982 Py_INCREF(Py_None);
5983 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005984}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005985#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005987
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005988#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005990"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991Set the current process's effective user id.");
5992
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005993static PyObject *
5994posix_seteuid (PyObject *self, PyObject *args)
5995{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005996 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005997 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005998 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005999 if (seteuid(euid) < 0) {
6000 return posix_error();
6001 } else {
6002 Py_INCREF(Py_None);
6003 return Py_None;
6004 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006005}
6006#endif /* HAVE_SETEUID */
6007
6008#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006009PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006010"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006011Set the current process's effective group id.");
6012
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006013static PyObject *
6014posix_setegid (PyObject *self, PyObject *args)
6015{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006016 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006017 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006018 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006019 if (setegid(egid) < 0) {
6020 return posix_error();
6021 } else {
6022 Py_INCREF(Py_None);
6023 return Py_None;
6024 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006025}
6026#endif /* HAVE_SETEGID */
6027
6028#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006030"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031Set the current process's real and effective user ids.");
6032
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006033static PyObject *
6034posix_setreuid (PyObject *self, PyObject *args)
6035{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006036 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006037 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6038 _Py_Uid_Converter, &ruid,
6039 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006040 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006041 if (setreuid(ruid, euid) < 0) {
6042 return posix_error();
6043 } else {
6044 Py_INCREF(Py_None);
6045 return Py_None;
6046 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006047}
6048#endif /* HAVE_SETREUID */
6049
6050#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006052"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053Set the current process's real and effective group ids.");
6054
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006055static PyObject *
6056posix_setregid (PyObject *self, PyObject *args)
6057{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006058 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006059 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6060 _Py_Gid_Converter, &rgid,
6061 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006062 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006063 if (setregid(rgid, egid) < 0) {
6064 return posix_error();
6065 } else {
6066 Py_INCREF(Py_None);
6067 return Py_None;
6068 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006069}
6070#endif /* HAVE_SETREGID */
6071
Guido van Rossumb6775db1994-08-01 11:34:53 +00006072#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006074"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006076
Barry Warsaw53699e91996-12-10 23:23:01 +00006077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006078posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006079{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006080 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006081 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006082 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006083 if (setgid(gid) < 0)
6084 return posix_error();
6085 Py_INCREF(Py_None);
6086 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006087}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006088#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006089
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006090#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006091PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006092"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006093Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006094
6095static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006096posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006097{
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006098 Py_ssize_t i, len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006099 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006100
Victor Stinnerd6f85422010-05-05 23:33:33 +00006101 if (!PySequence_Check(groups)) {
6102 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6103 return NULL;
6104 }
6105 len = PySequence_Size(groups);
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006106 if (len < 0) {
6107 return NULL;
6108 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006109 if (len > MAX_GROUPS) {
6110 PyErr_SetString(PyExc_ValueError, "too many groups");
6111 return NULL;
6112 }
6113 for(i = 0; i < len; i++) {
6114 PyObject *elem;
6115 elem = PySequence_GetItem(groups, i);
6116 if (!elem)
6117 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006118 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6119 PyErr_SetString(PyExc_TypeError,
6120 "groups must be integers");
6121 Py_DECREF(elem);
6122 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006123 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006124 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006125 Py_DECREF(elem);
6126 return NULL;
6127 }
6128 }
6129 Py_DECREF(elem);
6130 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006131
Victor Stinnerd6f85422010-05-05 23:33:33 +00006132 if (setgroups(len, grouplist) < 0)
6133 return posix_error();
6134 Py_INCREF(Py_None);
6135 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006136}
6137#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006138
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006139#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006140static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006141wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006142{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006143 PyObject *result;
6144 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006145
Victor Stinnerd6f85422010-05-05 23:33:33 +00006146 if (pid == -1)
6147 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006148
Victor Stinnerd6f85422010-05-05 23:33:33 +00006149 if (struct_rusage == NULL) {
6150 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6151 if (m == NULL)
6152 return NULL;
6153 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6154 Py_DECREF(m);
6155 if (struct_rusage == NULL)
6156 return NULL;
6157 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006158
Victor Stinnerd6f85422010-05-05 23:33:33 +00006159 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6160 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6161 if (!result)
6162 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006163
6164#ifndef doubletime
6165#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6166#endif
6167
Victor Stinnerd6f85422010-05-05 23:33:33 +00006168 PyStructSequence_SET_ITEM(result, 0,
6169 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6170 PyStructSequence_SET_ITEM(result, 1,
6171 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006172#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006173 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6174 SET_INT(result, 2, ru->ru_maxrss);
6175 SET_INT(result, 3, ru->ru_ixrss);
6176 SET_INT(result, 4, ru->ru_idrss);
6177 SET_INT(result, 5, ru->ru_isrss);
6178 SET_INT(result, 6, ru->ru_minflt);
6179 SET_INT(result, 7, ru->ru_majflt);
6180 SET_INT(result, 8, ru->ru_nswap);
6181 SET_INT(result, 9, ru->ru_inblock);
6182 SET_INT(result, 10, ru->ru_oublock);
6183 SET_INT(result, 11, ru->ru_msgsnd);
6184 SET_INT(result, 12, ru->ru_msgrcv);
6185 SET_INT(result, 13, ru->ru_nsignals);
6186 SET_INT(result, 14, ru->ru_nvcsw);
6187 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006188#undef SET_INT
6189
Victor Stinnerd6f85422010-05-05 23:33:33 +00006190 if (PyErr_Occurred()) {
6191 Py_DECREF(result);
6192 return NULL;
6193 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006194
Victor Stinnerd6f85422010-05-05 23:33:33 +00006195 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006196}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006197#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006198
6199#ifdef HAVE_WAIT3
6200PyDoc_STRVAR(posix_wait3__doc__,
6201"wait3(options) -> (pid, status, rusage)\n\n\
6202Wait for completion of a child process.");
6203
6204static PyObject *
6205posix_wait3(PyObject *self, PyObject *args)
6206{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006207 pid_t pid;
6208 int options;
6209 struct rusage ru;
6210 WAIT_TYPE status;
6211 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006212
Victor Stinnerd6f85422010-05-05 23:33:33 +00006213 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6214 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006215
Victor Stinnerd6f85422010-05-05 23:33:33 +00006216 Py_BEGIN_ALLOW_THREADS
6217 pid = wait3(&status, options, &ru);
6218 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006219
Victor Stinnerd6f85422010-05-05 23:33:33 +00006220 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006221}
6222#endif /* HAVE_WAIT3 */
6223
6224#ifdef HAVE_WAIT4
6225PyDoc_STRVAR(posix_wait4__doc__,
6226"wait4(pid, options) -> (pid, status, rusage)\n\n\
6227Wait for completion of a given child process.");
6228
6229static PyObject *
6230posix_wait4(PyObject *self, PyObject *args)
6231{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006232 pid_t pid;
6233 int options;
6234 struct rusage ru;
6235 WAIT_TYPE status;
6236 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006237
Victor Stinnerd6f85422010-05-05 23:33:33 +00006238 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6239 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006240
Victor Stinnerd6f85422010-05-05 23:33:33 +00006241 Py_BEGIN_ALLOW_THREADS
6242 pid = wait4(pid, &status, options, &ru);
6243 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006244
Victor Stinnerd6f85422010-05-05 23:33:33 +00006245 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006246}
6247#endif /* HAVE_WAIT4 */
6248
Guido van Rossumb6775db1994-08-01 11:34:53 +00006249#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006250PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006251"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006252Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006253
Barry Warsaw53699e91996-12-10 23:23:01 +00006254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006255posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006256{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006257 pid_t pid;
6258 int options;
6259 WAIT_TYPE status;
6260 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006261
Victor Stinnerd6f85422010-05-05 23:33:33 +00006262 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6263 return NULL;
6264 Py_BEGIN_ALLOW_THREADS
6265 pid = waitpid(pid, &status, options);
6266 Py_END_ALLOW_THREADS
6267 if (pid == -1)
6268 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006269
Victor Stinnerd6f85422010-05-05 23:33:33 +00006270 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006271}
6272
Tim Petersab034fa2002-02-01 11:27:43 +00006273#elif defined(HAVE_CWAIT)
6274
6275/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006277"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006279
6280static PyObject *
6281posix_waitpid(PyObject *self, PyObject *args)
6282{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006283 Py_intptr_t pid;
6284 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006285
Victor Stinnerd6f85422010-05-05 23:33:33 +00006286 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6287 return NULL;
6288 Py_BEGIN_ALLOW_THREADS
6289 pid = _cwait(&status, pid, options);
6290 Py_END_ALLOW_THREADS
6291 if (pid == -1)
6292 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006293
Victor Stinnerd6f85422010-05-05 23:33:33 +00006294 /* shift the status left a byte so this is more like the POSIX waitpid */
6295 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006296}
6297#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006298
Guido van Rossumad0ee831995-03-01 10:34:45 +00006299#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006302Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006303
Barry Warsaw53699e91996-12-10 23:23:01 +00006304static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006305posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006306{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006307 pid_t pid;
6308 WAIT_TYPE status;
6309 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006310
Victor Stinnerd6f85422010-05-05 23:33:33 +00006311 Py_BEGIN_ALLOW_THREADS
6312 pid = wait(&status);
6313 Py_END_ALLOW_THREADS
6314 if (pid == -1)
6315 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006316
Victor Stinnerd6f85422010-05-05 23:33:33 +00006317 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006318}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006319#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006321
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006322PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006323"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006324Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006325
Barry Warsaw53699e91996-12-10 23:23:01 +00006326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006327posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006328{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006329#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006330 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006331#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006332#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006333 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006334#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006335 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006336#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006337#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006338}
6339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006340
Guido van Rossumb6775db1994-08-01 11:34:53 +00006341#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006342PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006343"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006344Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006345
Barry Warsaw53699e91996-12-10 23:23:01 +00006346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006347posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006348{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006349 PyObject* v;
6350 char buf[MAXPATHLEN];
6351 char *path;
6352 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006353#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006354 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006355#endif
6356
Victor Stinnerd6f85422010-05-05 23:33:33 +00006357 if (!PyArg_ParseTuple(args, "et:readlink",
6358 Py_FileSystemDefaultEncoding, &path))
6359 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006360#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006361 v = PySequence_GetItem(args, 0);
6362 if (v == NULL) {
6363 PyMem_Free(path);
6364 return NULL;
6365 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006366
Victor Stinnerd6f85422010-05-05 23:33:33 +00006367 if (PyUnicode_Check(v)) {
6368 arg_is_unicode = 1;
6369 }
6370 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006371#endif
6372
Victor Stinnerd6f85422010-05-05 23:33:33 +00006373 Py_BEGIN_ALLOW_THREADS
6374 n = readlink(path, buf, (int) sizeof buf);
6375 Py_END_ALLOW_THREADS
6376 if (n < 0)
6377 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006378
Victor Stinnerd6f85422010-05-05 23:33:33 +00006379 PyMem_Free(path);
6380 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006381#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006382 if (arg_is_unicode) {
6383 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006384
Victor Stinnerd6f85422010-05-05 23:33:33 +00006385 w = PyUnicode_FromEncodedObject(v,
6386 Py_FileSystemDefaultEncoding,
6387 "strict");
6388 if (w != NULL) {
6389 Py_DECREF(v);
6390 v = w;
6391 }
6392 else {
6393 /* fall back to the original byte string, as
6394 discussed in patch #683592 */
6395 PyErr_Clear();
6396 }
6397 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006398#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006399 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006400}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006403
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006405PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006406"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006407Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006408
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006410posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006411{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006412 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006413}
6414#endif /* HAVE_SYMLINK */
6415
6416
6417#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006418#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6419static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006420system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006421{
6422 ULONG value = 0;
6423
6424 Py_BEGIN_ALLOW_THREADS
6425 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6426 Py_END_ALLOW_THREADS
6427
6428 return value;
6429}
6430
6431static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006432posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006433{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006434 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006435 return Py_BuildValue("ddddd",
6436 (double)0 /* t.tms_utime / HZ */,
6437 (double)0 /* t.tms_stime / HZ */,
6438 (double)0 /* t.tms_cutime / HZ */,
6439 (double)0 /* t.tms_cstime / HZ */,
6440 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006441}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006442#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006443#define NEED_TICKS_PER_SECOND
6444static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006445static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006446posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006447{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006448 struct tms t;
6449 clock_t c;
6450 errno = 0;
6451 c = times(&t);
6452 if (c == (clock_t) -1)
6453 return posix_error();
6454 return Py_BuildValue("ddddd",
6455 (double)t.tms_utime / ticks_per_second,
6456 (double)t.tms_stime / ticks_per_second,
6457 (double)t.tms_cutime / ticks_per_second,
6458 (double)t.tms_cstime / ticks_per_second,
6459 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006460}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006461#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006462#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006463
6464
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006465#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006466#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006467static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006468posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006469{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006470 FILETIME create, exit, kernel, user;
6471 HANDLE hProc;
6472 hProc = GetCurrentProcess();
6473 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6474 /* The fields of a FILETIME structure are the hi and lo part
6475 of a 64-bit value expressed in 100 nanosecond units.
6476 1e7 is one second in such units; 1e-7 the inverse.
6477 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6478 */
6479 return Py_BuildValue(
6480 "ddddd",
6481 (double)(user.dwHighDateTime*429.4967296 +
6482 user.dwLowDateTime*1e-7),
6483 (double)(kernel.dwHighDateTime*429.4967296 +
6484 kernel.dwLowDateTime*1e-7),
6485 (double)0,
6486 (double)0,
6487 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006488}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006489#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006490
6491#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006493"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006494Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006495#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006497
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006498#ifdef HAVE_GETSID
6499PyDoc_STRVAR(posix_getsid__doc__,
6500"getsid(pid) -> sid\n\n\
6501Call the system call getsid().");
6502
6503static PyObject *
6504posix_getsid(PyObject *self, PyObject *args)
6505{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006506 pid_t pid;
6507 int sid;
6508 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6509 return NULL;
6510 sid = getsid(pid);
6511 if (sid < 0)
6512 return posix_error();
6513 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006514}
6515#endif /* HAVE_GETSID */
6516
6517
Guido van Rossumb6775db1994-08-01 11:34:53 +00006518#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006519PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006520"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006522
Barry Warsaw53699e91996-12-10 23:23:01 +00006523static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006524posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006525{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006526 if (setsid() < 0)
6527 return posix_error();
6528 Py_INCREF(Py_None);
6529 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006530}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006531#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006532
Guido van Rossumb6775db1994-08-01 11:34:53 +00006533#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006534PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006535"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006536Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006537
Barry Warsaw53699e91996-12-10 23:23:01 +00006538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006539posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006540{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006541 pid_t pid;
6542 int pgrp;
6543 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6544 return NULL;
6545 if (setpgid(pid, pgrp) < 0)
6546 return posix_error();
6547 Py_INCREF(Py_None);
6548 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006549}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006550#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006552
Guido van Rossumb6775db1994-08-01 11:34:53 +00006553#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006554PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006555"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006556Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006557
Barry Warsaw53699e91996-12-10 23:23:01 +00006558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006559posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006560{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006561 int fd;
6562 pid_t pgid;
6563 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6564 return NULL;
6565 pgid = tcgetpgrp(fd);
6566 if (pgid < 0)
6567 return posix_error();
6568 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006569}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006570#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006571
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006572
Guido van Rossumb6775db1994-08-01 11:34:53 +00006573#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006574PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006575"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006576Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006577
Barry Warsaw53699e91996-12-10 23:23:01 +00006578static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006579posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006580{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006581 int fd;
6582 pid_t pgid;
6583 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6584 return NULL;
6585 if (tcsetpgrp(fd, pgid) < 0)
6586 return posix_error();
6587 Py_INCREF(Py_None);
6588 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006589}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006590#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006591
Guido van Rossum687dd131993-05-17 08:34:16 +00006592/* Functions acting on file descriptors */
6593
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006594PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006595"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006596Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006597
Barry Warsaw53699e91996-12-10 23:23:01 +00006598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006599posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006600{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006601 char *file = NULL;
6602 int flag;
6603 int mode = 0777;
6604 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006605
6606#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006607 Py_UNICODE *wpath;
6608 if (PyArg_ParseTuple(args, "ui|i:mkdir", &wpath, &flag, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006609 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006610 fd = _wopen(wpath, flag, mode);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006611 Py_END_ALLOW_THREADS
6612 if (fd < 0)
6613 return posix_error();
6614 return PyInt_FromLong((long)fd);
6615 }
6616 /* Drop the argument parsing error as narrow strings
6617 are also valid. */
6618 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006619#endif
6620
Victor Stinnerd6f85422010-05-05 23:33:33 +00006621 if (!PyArg_ParseTuple(args, "eti|i",
6622 Py_FileSystemDefaultEncoding, &file,
6623 &flag, &mode))
6624 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006625
Victor Stinnerd6f85422010-05-05 23:33:33 +00006626 Py_BEGIN_ALLOW_THREADS
6627 fd = open(file, flag, mode);
6628 Py_END_ALLOW_THREADS
6629 if (fd < 0)
6630 return posix_error_with_allocated_filename(file);
6631 PyMem_Free(file);
6632 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006633}
6634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006637"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006638Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006639
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006640/*
6641The underscore at end of function name avoids a name clash with the libc
6642function posix_close.
6643*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006644static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006645posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006646{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006647 int fd, res;
6648 if (!PyArg_ParseTuple(args, "i:close", &fd))
6649 return NULL;
6650 if (!_PyVerify_fd(fd))
6651 return posix_error();
6652 Py_BEGIN_ALLOW_THREADS
6653 res = close(fd);
6654 Py_END_ALLOW_THREADS
6655 if (res < 0)
6656 return posix_error();
6657 Py_INCREF(Py_None);
6658 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006659}
6660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006661
Victor Stinnerd6f85422010-05-05 23:33:33 +00006662PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006663"closerange(fd_low, fd_high)\n\n\
6664Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6665
6666static PyObject *
6667posix_closerange(PyObject *self, PyObject *args)
6668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006669 int fd_from, fd_to, i;
6670 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6671 return NULL;
6672 Py_BEGIN_ALLOW_THREADS
6673 for (i = fd_from; i < fd_to; i++)
6674 if (_PyVerify_fd(i))
6675 close(i);
6676 Py_END_ALLOW_THREADS
6677 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006678}
6679
6680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006681PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006682"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006683Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006684
Barry Warsaw53699e91996-12-10 23:23:01 +00006685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006686posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006687{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006688 int fd;
6689 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6690 return NULL;
6691 if (!_PyVerify_fd(fd))
6692 return posix_error();
6693 Py_BEGIN_ALLOW_THREADS
6694 fd = dup(fd);
6695 Py_END_ALLOW_THREADS
6696 if (fd < 0)
6697 return posix_error();
6698 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006699}
6700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006701
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006702PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006703"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006704Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006705
Barry Warsaw53699e91996-12-10 23:23:01 +00006706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006707posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006708{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006709 int fd, fd2, res;
6710 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6711 return NULL;
6712 if (!_PyVerify_fd_dup2(fd, fd2))
6713 return posix_error();
6714 Py_BEGIN_ALLOW_THREADS
6715 res = dup2(fd, fd2);
6716 Py_END_ALLOW_THREADS
6717 if (res < 0)
6718 return posix_error();
6719 Py_INCREF(Py_None);
6720 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006721}
6722
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006723
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006724PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006725"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006726Set the current position of a file descriptor.\n\
6727Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006728
Barry Warsaw53699e91996-12-10 23:23:01 +00006729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006730posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006731{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006732 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006733#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006734 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006735#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006736 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006737#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006738 PyObject *posobj;
6739 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6740 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006741#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006742 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6743 switch (how) {
6744 case 0: how = SEEK_SET; break;
6745 case 1: how = SEEK_CUR; break;
6746 case 2: how = SEEK_END; break;
6747 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006748#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006749
6750#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006751 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006752#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006753 pos = PyLong_Check(posobj) ?
6754 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006755#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006756 if (PyErr_Occurred())
6757 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006758
Victor Stinnerd6f85422010-05-05 23:33:33 +00006759 if (!_PyVerify_fd(fd))
6760 return posix_error();
6761 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006762#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006763 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006764#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006765 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006766#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006767 Py_END_ALLOW_THREADS
6768 if (res < 0)
6769 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006770
6771#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006772 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006773#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006774 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006775#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006776}
6777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006778
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006779PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006780"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006781Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006782
Barry Warsaw53699e91996-12-10 23:23:01 +00006783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006784posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006785{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006786 int fd, size, n;
6787 PyObject *buffer;
6788 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6789 return NULL;
6790 if (size < 0) {
6791 errno = EINVAL;
6792 return posix_error();
6793 }
6794 buffer = PyString_FromStringAndSize((char *)NULL, size);
6795 if (buffer == NULL)
6796 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006797 if (!_PyVerify_fd(fd)) {
6798 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006799 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006800 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006801 Py_BEGIN_ALLOW_THREADS
6802 n = read(fd, PyString_AsString(buffer), size);
6803 Py_END_ALLOW_THREADS
6804 if (n < 0) {
6805 Py_DECREF(buffer);
6806 return posix_error();
6807 }
6808 if (n != size)
6809 _PyString_Resize(&buffer, n);
6810 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006811}
6812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006813
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006814PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006815"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006816Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817
Barry Warsaw53699e91996-12-10 23:23:01 +00006818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006819posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006820{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006821 Py_buffer pbuf;
6822 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006823 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006824
Victor Stinnerd6f85422010-05-05 23:33:33 +00006825 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6826 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006827 if (!_PyVerify_fd(fd)) {
6828 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006829 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006830 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006831 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006832 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006833#if defined(MS_WIN64) || defined(MS_WINDOWS)
6834 if (len > INT_MAX)
6835 len = INT_MAX;
6836 size = write(fd, pbuf.buf, (int)len);
6837#else
6838 size = write(fd, pbuf.buf, len);
6839#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006840 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006841 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006842 if (size < 0)
6843 return posix_error();
6844 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006845}
6846
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006848PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006849"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006850Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006851
Barry Warsaw53699e91996-12-10 23:23:01 +00006852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006853posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006854{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006855 int fd;
6856 STRUCT_STAT st;
6857 int res;
6858 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6859 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006860#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006861 /* on OpenVMS we must ensure that all bytes are written to the file */
6862 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006863#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006864 if (!_PyVerify_fd(fd))
6865 return posix_error();
6866 Py_BEGIN_ALLOW_THREADS
6867 res = FSTAT(fd, &st);
6868 Py_END_ALLOW_THREADS
6869 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006870#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006871 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006872#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006873 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006874#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006875 }
Tim Peters5aa91602002-01-30 05:46:57 +00006876
Victor Stinnerd6f85422010-05-05 23:33:33 +00006877 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006878}
6879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006882"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006883Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006884
Barry Warsaw53699e91996-12-10 23:23:01 +00006885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006886posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006887{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006888 int fd;
6889 char *orgmode = "r";
6890 int bufsize = -1;
6891 FILE *fp;
6892 PyObject *f;
6893 char *mode;
6894 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6895 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006896
Victor Stinnerd6f85422010-05-05 23:33:33 +00006897 /* Sanitize mode. See fileobject.c */
6898 mode = PyMem_MALLOC(strlen(orgmode)+3);
6899 if (!mode) {
6900 PyErr_NoMemory();
6901 return NULL;
6902 }
6903 strcpy(mode, orgmode);
6904 if (_PyFile_SanitizeMode(mode)) {
6905 PyMem_FREE(mode);
6906 return NULL;
6907 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006908 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006909 PyMem_FREE(mode);
6910 return posix_error();
6911 }
6912#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6913 {
6914 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006915 const char *msg;
6916 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006917 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6918 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006919 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006920 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006921 EISDIR, msg, "<fdopen>");
6922 if (exc) {
6923 PyErr_SetObject(PyExc_IOError, exc);
6924 Py_DECREF(exc);
6925 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006926 return NULL;
6927 }
6928 }
6929#endif
Benjamin Petersond3035d52016-12-03 13:03:18 -08006930 /* The dummy filename used here must be kept in sync with the value
6931 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6932 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
Benjamin Petersone95048e2016-12-03 13:05:40 -08006933 if (f == NULL) {
Benjamin Peterson9ea8faf2016-12-03 13:07:47 -08006934 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006935 return NULL;
Benjamin Petersone95048e2016-12-03 13:05:40 -08006936 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006937 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006938#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006939 if (mode[0] == 'a') {
6940 /* try to make sure the O_APPEND flag is set */
6941 int flags;
6942 flags = fcntl(fd, F_GETFL);
6943 if (flags != -1)
6944 fcntl(fd, F_SETFL, flags | O_APPEND);
6945 fp = fdopen(fd, mode);
6946 if (fp == NULL && flags != -1)
6947 /* restore old mode if fdopen failed */
6948 fcntl(fd, F_SETFL, flags);
6949 } else {
6950 fp = fdopen(fd, mode);
6951 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006952#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006953 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006954#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006955 Py_END_ALLOW_THREADS
6956 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006957 if (fp == NULL) {
6958 Py_DECREF(f);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006959 return posix_error();
Benjamin Petersond3035d52016-12-03 13:03:18 -08006960 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006961 /* We now know we will succeed, so initialize the file object. */
6962 ((PyFileObject *)f)->f_fp = fp;
6963 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006964 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006965}
6966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006967PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006968"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006969Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006970connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006971
6972static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006973posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006974{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006975 int fd;
6976 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6977 return NULL;
6978 if (!_PyVerify_fd(fd))
6979 return PyBool_FromLong(0);
6980 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006981}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006982
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006983#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006984PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006985"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006986Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006987
Barry Warsaw53699e91996-12-10 23:23:01 +00006988static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006989posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006990{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006991#if defined(PYOS_OS2)
6992 HFILE read, write;
6993 APIRET rc;
6994
Victor Stinnerd6f85422010-05-05 23:33:33 +00006995 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006996 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006997 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006998 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006999 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007000
7001 return Py_BuildValue("(ii)", read, write);
7002#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007003#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007004 int fds[2];
7005 int res;
7006 Py_BEGIN_ALLOW_THREADS
7007 res = pipe(fds);
7008 Py_END_ALLOW_THREADS
7009 if (res != 0)
7010 return posix_error();
7011 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007012#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00007013 HANDLE read, write;
7014 int read_fd, write_fd;
7015 BOOL ok;
7016 Py_BEGIN_ALLOW_THREADS
7017 ok = CreatePipe(&read, &write, NULL, 0);
7018 Py_END_ALLOW_THREADS
7019 if (!ok)
7020 return win32_error("CreatePipe", NULL);
7021 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7022 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7023 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007024#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007025#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007026}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007027#endif /* HAVE_PIPE */
7028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007029
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007030#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007031PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007032"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007034
Barry Warsaw53699e91996-12-10 23:23:01 +00007035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007036posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007037{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007038 char *filename;
7039 int mode = 0666;
7040 int res;
7041 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7042 return NULL;
7043 Py_BEGIN_ALLOW_THREADS
7044 res = mkfifo(filename, mode);
7045 Py_END_ALLOW_THREADS
7046 if (res < 0)
7047 return posix_error();
7048 Py_INCREF(Py_None);
7049 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007050}
7051#endif
7052
7053
Neal Norwitz11690112002-07-30 01:08:28 +00007054#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007056"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007057Create a filesystem node (file, device special file or named pipe)\n\
7058named filename. mode specifies both the permissions to use and the\n\
7059type of node to be created, being combined (bitwise OR) with one of\n\
7060S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007061device defines the newly created device special file (probably using\n\
7062os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007063
7064
7065static PyObject *
7066posix_mknod(PyObject *self, PyObject *args)
7067{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007068 char *filename;
7069 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007070 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007071 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007072 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7073 &filename, &mode,
7074 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007075 return NULL;
7076 Py_BEGIN_ALLOW_THREADS
7077 res = mknod(filename, mode, device);
7078 Py_END_ALLOW_THREADS
7079 if (res < 0)
7080 return posix_error();
7081 Py_INCREF(Py_None);
7082 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007083}
7084#endif
7085
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007086#ifdef HAVE_DEVICE_MACROS
7087PyDoc_STRVAR(posix_major__doc__,
7088"major(device) -> major number\n\
7089Extracts a device major number from a raw device number.");
7090
7091static PyObject *
7092posix_major(PyObject *self, PyObject *args)
7093{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007094 dev_t device;
7095 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007096 return NULL;
7097 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007098}
7099
7100PyDoc_STRVAR(posix_minor__doc__,
7101"minor(device) -> minor number\n\
7102Extracts a device minor number from a raw device number.");
7103
7104static PyObject *
7105posix_minor(PyObject *self, PyObject *args)
7106{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007107 dev_t device;
7108 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007109 return NULL;
7110 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007111}
7112
7113PyDoc_STRVAR(posix_makedev__doc__,
7114"makedev(major, minor) -> device number\n\
7115Composes a raw device number from the major and minor device numbers.");
7116
7117static PyObject *
7118posix_makedev(PyObject *self, PyObject *args)
7119{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007120 int major, minor;
7121 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7122 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007123 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007124}
7125#endif /* device macros */
7126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007127
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007128#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007129PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007130"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007131Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007132
Barry Warsaw53699e91996-12-10 23:23:01 +00007133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007134posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007135{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007136 int fd;
7137 off_t length;
7138 int res;
7139 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007140
Victor Stinnerd6f85422010-05-05 23:33:33 +00007141 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7142 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007143
7144#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007145 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007146#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007147 length = PyLong_Check(lenobj) ?
7148 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007149#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007150 if (PyErr_Occurred())
7151 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007152
Victor Stinnerd6f85422010-05-05 23:33:33 +00007153 Py_BEGIN_ALLOW_THREADS
7154 res = ftruncate(fd, length);
7155 Py_END_ALLOW_THREADS
7156 if (res < 0)
7157 return posix_error();
7158 Py_INCREF(Py_None);
7159 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007160}
7161#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007162
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007163#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007164PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007165"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007166Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007167
Fred Drake762e2061999-08-26 17:23:54 +00007168/* Save putenv() parameters as values here, so we can collect them when they
7169 * get re-set with another call for the same key. */
7170static PyObject *posix_putenv_garbage;
7171
Tim Peters5aa91602002-01-30 05:46:57 +00007172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007173posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007174{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007175 char *s1, *s2;
7176 char *newenv;
7177 PyObject *newstr;
7178 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007179
Victor Stinnerd6f85422010-05-05 23:33:33 +00007180 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7181 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007182
7183#if defined(PYOS_OS2)
7184 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7185 APIRET rc;
7186
Guido van Rossumd48f2521997-12-05 22:19:34 +00007187 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7188 if (rc != NO_ERROR)
7189 return os2_error(rc);
7190
7191 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7192 APIRET rc;
7193
Guido van Rossumd48f2521997-12-05 22:19:34 +00007194 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7195 if (rc != NO_ERROR)
7196 return os2_error(rc);
7197 } else {
7198#endif
7199
Serhiy Storchaka787826c2017-06-25 09:50:00 +03007200 /* Search from index 1 because on Windows starting '=' is allowed for
7201 defining hidden environment variables. */
7202 if (*s1 == '\0' || strchr(s1 + 1, '=') != NULL) {
7203 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
7204 return NULL;
7205 }
7206
Victor Stinnerd6f85422010-05-05 23:33:33 +00007207 /* XXX This can leak memory -- not easy to fix :-( */
7208 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007209#ifdef MS_WINDOWS
7210 if (_MAX_ENV < (len - 1)) {
7211 PyErr_Format(PyExc_ValueError,
7212 "the environment variable is longer than %u bytes",
7213 _MAX_ENV);
7214 return NULL;
7215 }
7216#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007217 /* len includes space for a trailing \0; the size arg to
7218 PyString_FromStringAndSize does not count that */
7219 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7220 if (newstr == NULL)
7221 return PyErr_NoMemory();
7222 newenv = PyString_AS_STRING(newstr);
7223 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7224 if (putenv(newenv)) {
7225 Py_DECREF(newstr);
7226 posix_error();
7227 return NULL;
7228 }
7229 /* Install the first arg and newstr in posix_putenv_garbage;
7230 * this will cause previous value to be collected. This has to
7231 * happen after the real putenv() call because the old value
7232 * was still accessible until then. */
7233 if (PyDict_SetItem(posix_putenv_garbage,
7234 PyTuple_GET_ITEM(args, 0), newstr)) {
7235 /* really not much we can do; just leak */
7236 PyErr_Clear();
7237 }
7238 else {
7239 Py_DECREF(newstr);
7240 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007241
7242#if defined(PYOS_OS2)
7243 }
7244#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007245 Py_INCREF(Py_None);
7246 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007247}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007248#endif /* putenv */
7249
Guido van Rossumc524d952001-10-19 01:31:59 +00007250#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007251PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007252"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007253Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007254
7255static PyObject *
7256posix_unsetenv(PyObject *self, PyObject *args)
7257{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007258 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007259#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007260 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007261#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007262
Victor Stinnerd6f85422010-05-05 23:33:33 +00007263 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7264 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007265
Charles-François Natali93a11752011-11-27 13:01:35 +01007266#ifdef HAVE_BROKEN_UNSETENV
7267 unsetenv(s1);
7268#else
Victor Stinner53853c32011-11-22 22:20:13 +01007269 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007270 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007271 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007272#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007273
Victor Stinnerd6f85422010-05-05 23:33:33 +00007274 /* Remove the key from posix_putenv_garbage;
7275 * this will cause it to be collected. This has to
7276 * happen after the real unsetenv() call because the
7277 * old value was still accessible until then.
7278 */
7279 if (PyDict_DelItem(posix_putenv_garbage,
7280 PyTuple_GET_ITEM(args, 0))) {
7281 /* really not much we can do; just leak */
7282 PyErr_Clear();
7283 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007284
Victor Stinnerd6f85422010-05-05 23:33:33 +00007285 Py_INCREF(Py_None);
7286 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007287}
7288#endif /* unsetenv */
7289
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007290PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007291"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007292Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007293
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007294static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007295posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007296{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007297 int code;
7298 char *message;
7299 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7300 return NULL;
7301 message = strerror(code);
7302 if (message == NULL) {
7303 PyErr_SetString(PyExc_ValueError,
7304 "strerror() argument out of range");
7305 return NULL;
7306 }
7307 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007308}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007309
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007310
Guido van Rossumc9641791998-08-04 15:26:23 +00007311#ifdef HAVE_SYS_WAIT_H
7312
Fred Drake106c1a02002-04-23 15:58:02 +00007313#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007314PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007315"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007316Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007317
7318static PyObject *
7319posix_WCOREDUMP(PyObject *self, PyObject *args)
7320{
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:WCOREDUMP", &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(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007328}
7329#endif /* WCOREDUMP */
7330
7331#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007332PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007333"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007334Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007335job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007336
7337static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007338posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007339{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007340 WAIT_TYPE status;
7341 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007342
Victor Stinnerd6f85422010-05-05 23:33:33 +00007343 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7344 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007345
Victor Stinnerd6f85422010-05-05 23:33:33 +00007346 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007347}
7348#endif /* WIFCONTINUED */
7349
Guido van Rossumc9641791998-08-04 15:26:23 +00007350#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007351PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007352"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007353Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007354
7355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007356posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007357{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007358 WAIT_TYPE status;
7359 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007360
Victor Stinnerd6f85422010-05-05 23:33:33 +00007361 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7362 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007363
Victor Stinnerd6f85422010-05-05 23:33:33 +00007364 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007365}
7366#endif /* WIFSTOPPED */
7367
7368#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007369PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007370"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007371Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007372
7373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007374posix_WIFSIGNALED(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:WIFSIGNALED", &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(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007383}
7384#endif /* WIFSIGNALED */
7385
7386#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007387PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007388"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007389Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007390system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007391
7392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007393posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007394{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007395 WAIT_TYPE status;
7396 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007397
Victor Stinnerd6f85422010-05-05 23:33:33 +00007398 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7399 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007400
Victor Stinnerd6f85422010-05-05 23:33:33 +00007401 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007402}
7403#endif /* WIFEXITED */
7404
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007405#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007406PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007407"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007408Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007409
7410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007411posix_WEXITSTATUS(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:WEXITSTATUS", &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", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007420}
7421#endif /* WEXITSTATUS */
7422
7423#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007424PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007425"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007426Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007427value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007428
7429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007430posix_WTERMSIG(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:WTERMSIG", &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", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007439}
7440#endif /* WTERMSIG */
7441
7442#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007443PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007444"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007445Return the signal that stopped the process that provided\n\
7446the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007447
7448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007449posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007450{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007451 WAIT_TYPE status;
7452 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007453
Victor Stinnerd6f85422010-05-05 23:33:33 +00007454 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7455 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007456
Victor Stinnerd6f85422010-05-05 23:33:33 +00007457 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007458}
7459#endif /* WSTOPSIG */
7460
7461#endif /* HAVE_SYS_WAIT_H */
7462
7463
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007464#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007465#ifdef _SCO_DS
7466/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7467 needed definitions in sys/statvfs.h */
7468#define _SVID3
7469#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007470#include <sys/statvfs.h>
7471
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007472static PyObject*
7473_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007474 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7475 if (v == NULL)
7476 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007477
7478#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007479 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7480 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7481 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7482 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7483 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7484 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7485 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7486 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7487 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7488 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007489#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007490 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7491 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7492 PyStructSequence_SET_ITEM(v, 2,
7493 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7494 PyStructSequence_SET_ITEM(v, 3,
7495 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7496 PyStructSequence_SET_ITEM(v, 4,
7497 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7498 PyStructSequence_SET_ITEM(v, 5,
7499 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7500 PyStructSequence_SET_ITEM(v, 6,
7501 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7502 PyStructSequence_SET_ITEM(v, 7,
7503 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7504 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7505 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007506#endif
7507
Victor Stinnerd6f85422010-05-05 23:33:33 +00007508 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007509}
7510
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007511PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007512"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007513Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007514
7515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007516posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007517{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007518 int fd, res;
7519 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007520
Victor Stinnerd6f85422010-05-05 23:33:33 +00007521 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7522 return NULL;
7523 Py_BEGIN_ALLOW_THREADS
7524 res = fstatvfs(fd, &st);
7525 Py_END_ALLOW_THREADS
7526 if (res != 0)
7527 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007528
Victor Stinnerd6f85422010-05-05 23:33:33 +00007529 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007530}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007531#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007532
7533
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007534#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007535#include <sys/statvfs.h>
7536
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007537PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007538"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007539Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007540
7541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007542posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007543{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007544 char *path;
7545 int res;
7546 struct statvfs st;
7547 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7548 return NULL;
7549 Py_BEGIN_ALLOW_THREADS
7550 res = statvfs(path, &st);
7551 Py_END_ALLOW_THREADS
7552 if (res != 0)
7553 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007554
Victor Stinnerd6f85422010-05-05 23:33:33 +00007555 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007556}
7557#endif /* HAVE_STATVFS */
7558
7559
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007561PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007562"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007563Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007564The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007565or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566
7567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007568posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007569{
7570 PyObject *result = NULL;
7571 char *dir = NULL;
7572 char *pfx = NULL;
7573 char *name;
7574
7575 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007576 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007577
7578 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007579 "tempnam is a potential security risk to your program") < 0)
7580 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007581
Antoine Pitroub0614612011-01-02 20:04:52 +00007582 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7583 "use the tempfile module", 1) < 0)
7584 return NULL;
7585
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007586#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007587 name = _tempnam(dir, pfx);
7588#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007589 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007590#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007591 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007592 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007593 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007594 free(name);
7595 return result;
7596}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007597#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007598
7599
7600#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007601PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007602"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007603Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007604
7605static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007606posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007607{
7608 FILE *fp;
7609
Antoine Pitroub0614612011-01-02 20:04:52 +00007610 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7611 "use the tempfile module", 1) < 0)
7612 return NULL;
7613
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007614 fp = tmpfile();
7615 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007616 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007617 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007618}
7619#endif
7620
7621
7622#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007623PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007624"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007625Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007626
7627static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007628posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007629{
7630 char buffer[L_tmpnam];
7631 char *name;
7632
Skip Montanaro95618b52001-08-18 18:52:10 +00007633 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007634 "tmpnam is a potential security risk to your program") < 0)
7635 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007636
Antoine Pitroub0614612011-01-02 20:04:52 +00007637 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7638 "use the tempfile module", 1) < 0)
7639 return NULL;
7640
Greg Wardb48bc172000-03-01 21:51:56 +00007641#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007642 name = tmpnam_r(buffer);
7643#else
7644 name = tmpnam(buffer);
7645#endif
7646 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007647 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007648#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007649 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007650#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007651 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007652#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007653 );
7654 PyErr_SetObject(PyExc_OSError, err);
7655 Py_XDECREF(err);
7656 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007657 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007658 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007659}
7660#endif
7661
7662
Fred Drakec9680921999-12-13 16:37:25 +00007663/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7664 * It maps strings representing configuration variable names to
7665 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007666 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007667 * rarely-used constants. There are three separate tables that use
7668 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007669 *
7670 * This code is always included, even if none of the interfaces that
7671 * need it are included. The #if hackery needed to avoid it would be
7672 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007673 */
7674struct constdef {
7675 char *name;
7676 long value;
7677};
7678
Fred Drake12c6e2d1999-12-14 21:25:03 +00007679static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007680conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007681 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007682{
7683 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007684 *valuep = PyInt_AS_LONG(arg);
7685 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007686 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007687 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007688 /* look up the value in the table using a binary search */
7689 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007690 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007691 size_t hi = tablesize;
7692 int cmp;
7693 char *confname = PyString_AS_STRING(arg);
7694 while (lo < hi) {
7695 mid = (lo + hi) / 2;
7696 cmp = strcmp(confname, table[mid].name);
7697 if (cmp < 0)
7698 hi = mid;
7699 else if (cmp > 0)
7700 lo = mid + 1;
7701 else {
7702 *valuep = table[mid].value;
7703 return 1;
7704 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007705 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007706 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007707 }
7708 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007709 PyErr_SetString(PyExc_TypeError,
7710 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007711 return 0;
7712}
7713
7714
7715#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7716static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007717#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007718 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007719#endif
7720#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007721 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007722#endif
Fred Drakec9680921999-12-13 16:37:25 +00007723#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007724 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007725#endif
7726#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007727 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007728#endif
7729#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007730 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007731#endif
7732#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007733 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007734#endif
7735#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007736 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007737#endif
7738#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007739 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007740#endif
7741#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007742 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007743#endif
7744#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007745 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007746#endif
7747#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007748 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007749#endif
7750#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007751 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007752#endif
7753#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007754 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007755#endif
7756#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007757 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007758#endif
7759#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007760 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007761#endif
7762#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007763 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007764#endif
7765#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007766 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007767#endif
7768};
7769
Fred Drakec9680921999-12-13 16:37:25 +00007770static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007771conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007772{
7773 return conv_confname(arg, valuep, posix_constants_pathconf,
7774 sizeof(posix_constants_pathconf)
7775 / sizeof(struct constdef));
7776}
7777#endif
7778
7779#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007780PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007781"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007782Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007783If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007784
7785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007786posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007787{
7788 PyObject *result = NULL;
7789 int name, fd;
7790
Fred Drake12c6e2d1999-12-14 21:25:03 +00007791 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7792 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007793 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007794
Stefan Krah93f7a322010-11-26 17:35:50 +00007795 errno = 0;
7796 limit = fpathconf(fd, name);
7797 if (limit == -1 && errno != 0)
7798 posix_error();
7799 else
7800 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007801 }
7802 return result;
7803}
7804#endif
7805
7806
7807#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007808PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007809"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007810Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007811If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007812
7813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007814posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007815{
7816 PyObject *result = NULL;
7817 int name;
7818 char *path;
7819
7820 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7821 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007822 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007823
Victor Stinnerd6f85422010-05-05 23:33:33 +00007824 errno = 0;
7825 limit = pathconf(path, name);
7826 if (limit == -1 && errno != 0) {
7827 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007828 /* could be a path or name problem */
7829 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007830 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007831 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007832 }
7833 else
7834 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007835 }
7836 return result;
7837}
7838#endif
7839
7840#ifdef HAVE_CONFSTR
7841static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007842#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007843 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007844#endif
7845#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007846 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007847#endif
7848#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007850#endif
7851#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007853#endif
7854#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007856#endif
Fred Drakec9680921999-12-13 16:37:25 +00007857#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007859#endif
7860#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007862#endif
7863#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007865#endif
7866#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
7869#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
Fred Draked86ed291999-12-15 15:34:33 +00007881#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007883#endif
Fred Drakec9680921999-12-13 16:37:25 +00007884#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007886#endif
Fred Draked86ed291999-12-15 15:34:33 +00007887#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007889#endif
7890#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007892#endif
7893#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007895#endif
7896#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007898#endif
Fred Drakec9680921999-12-13 16:37:25 +00007899#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007901#endif
7902#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007904#endif
7905#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
7908#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007910#endif
7911#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007913#endif
7914#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007916#endif
7917#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
7920#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007922#endif
7923#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
7926#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007928#endif
7929#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
7932#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007934#endif
7935#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007937#endif
7938#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007940#endif
7941#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007943#endif
7944#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007946#endif
Fred Draked86ed291999-12-15 15:34:33 +00007947#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007949#endif
7950#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007951 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007952#endif
7953#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007954 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007955#endif
7956#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007957 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007958#endif
7959#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007960 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007961#endif
7962#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007963 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007964#endif
7965#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007966 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007967#endif
7968#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007969 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007970#endif
7971#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007973#endif
7974#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007975 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007976#endif
7977#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007979#endif
7980#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007982#endif
7983#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007984 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007985#endif
Fred Drakec9680921999-12-13 16:37:25 +00007986};
7987
7988static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007989conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007990{
7991 return conv_confname(arg, valuep, posix_constants_confstr,
7992 sizeof(posix_constants_confstr)
7993 / sizeof(struct constdef));
7994}
7995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007996PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007997"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007998Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007999
8000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008001posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008002{
8003 PyObject *result = NULL;
8004 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00008005 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00008006
8007 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008008 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008009
Victor Stinnerd6f85422010-05-05 23:33:33 +00008010 errno = 0;
8011 len = confstr(name, buffer, sizeof(buffer));
8012 if (len == 0) {
8013 if (errno) {
8014 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008015 }
8016 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008017 result = Py_None;
8018 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00008019 }
8020 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00008021 else {
8022 if ((unsigned int)len >= sizeof(buffer)) {
8023 result = PyString_FromStringAndSize(NULL, len-1);
8024 if (result != NULL)
8025 confstr(name, PyString_AS_STRING(result), len);
8026 }
8027 else
8028 result = PyString_FromStringAndSize(buffer, len-1);
8029 }
8030 }
Fred Drakec9680921999-12-13 16:37:25 +00008031 return result;
8032}
8033#endif
8034
8035
8036#ifdef HAVE_SYSCONF
8037static struct constdef posix_constants_sysconf[] = {
8038#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008039 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008040#endif
8041#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008042 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008043#endif
8044#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008045 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008046#endif
8047#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008048 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008049#endif
8050#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008051 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008052#endif
8053#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008054 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008055#endif
8056#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008057 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008058#endif
8059#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008060 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008061#endif
8062#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008063 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008064#endif
8065#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008066 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008067#endif
Fred Draked86ed291999-12-15 15:34:33 +00008068#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008069 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008070#endif
8071#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008072 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008073#endif
Fred Drakec9680921999-12-13 16:37:25 +00008074#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008075 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008076#endif
Fred Drakec9680921999-12-13 16:37:25 +00008077#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008078 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008079#endif
8080#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008081 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008082#endif
8083#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008084 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008085#endif
8086#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008087 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008088#endif
8089#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008090 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008091#endif
Fred Draked86ed291999-12-15 15:34:33 +00008092#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008093 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008094#endif
Fred Drakec9680921999-12-13 16:37:25 +00008095#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008096 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008097#endif
8098#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008099 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008100#endif
8101#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008102 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008103#endif
8104#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008105 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008106#endif
8107#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008108 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008109#endif
Fred Draked86ed291999-12-15 15:34:33 +00008110#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008111 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008112#endif
Fred Drakec9680921999-12-13 16:37:25 +00008113#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008114 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008115#endif
8116#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008117 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008118#endif
8119#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008120 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008121#endif
8122#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008123 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008124#endif
8125#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008126 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008127#endif
8128#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008129 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008130#endif
8131#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008132 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008133#endif
8134#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008135 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008136#endif
8137#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008138 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008139#endif
8140#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008141 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008142#endif
8143#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008144 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008145#endif
8146#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008147 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008148#endif
8149#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008150 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008151#endif
8152#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008153 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008154#endif
8155#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008156 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008157#endif
8158#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008159 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008160#endif
8161#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008162 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008163#endif
8164#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008165 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008166#endif
8167#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008168 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008169#endif
8170#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008171 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008172#endif
8173#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008174 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008175#endif
8176#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008177 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008178#endif
8179#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008180 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008181#endif
Fred Draked86ed291999-12-15 15:34:33 +00008182#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008183 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008184#endif
Fred Drakec9680921999-12-13 16:37:25 +00008185#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008186 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008187#endif
8188#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008189 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008190#endif
8191#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008192 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008193#endif
Fred Draked86ed291999-12-15 15:34:33 +00008194#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008195 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008196#endif
Fred Drakec9680921999-12-13 16:37:25 +00008197#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008198 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008199#endif
Fred Draked86ed291999-12-15 15:34:33 +00008200#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008201 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008202#endif
8203#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008204 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008205#endif
Fred Drakec9680921999-12-13 16:37:25 +00008206#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008207 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008208#endif
8209#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008210 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008211#endif
8212#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008213 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008214#endif
8215#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008216 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008217#endif
Fred Draked86ed291999-12-15 15:34:33 +00008218#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008219 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008220#endif
Fred Drakec9680921999-12-13 16:37:25 +00008221#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008222 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008223#endif
8224#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008225 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008226#endif
8227#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008228 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008229#endif
8230#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008231 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008232#endif
8233#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008234 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008235#endif
8236#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008237 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008238#endif
8239#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008240 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008241#endif
Fred Draked86ed291999-12-15 15:34:33 +00008242#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008243 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008244#endif
Fred Drakec9680921999-12-13 16:37:25 +00008245#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008246 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008247#endif
8248#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008249 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008250#endif
Fred Draked86ed291999-12-15 15:34:33 +00008251#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008252 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008253#endif
Fred Drakec9680921999-12-13 16:37:25 +00008254#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008255 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
8257#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008258 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008259#endif
8260#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008261 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008264 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008267 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
8269#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008270 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008271#endif
8272#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008273 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008274#endif
8275#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008276 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008277#endif
8278#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008279 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
Fred Draked86ed291999-12-15 15:34:33 +00008281#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008282 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008283#endif
8284#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008285 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008286#endif
Fred Drakec9680921999-12-13 16:37:25 +00008287#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008288 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008289#endif
8290#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008291 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008292#endif
8293#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008294 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008295#endif
8296#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008297 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008298#endif
8299#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008300 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008301#endif
8302#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008303 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008304#endif
8305#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008306 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008307#endif
8308#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008309 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008310#endif
8311#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008312 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008313#endif
8314#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008315 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008316#endif
8317#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008318 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008319#endif
8320#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008321 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008322#endif
8323#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008324 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008325#endif
8326#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008327 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008328#endif
8329#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008330 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008331#endif
8332#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008333 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008334#endif
8335#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008336 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008337#endif
8338#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008339 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008340#endif
8341#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008342 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008343#endif
8344#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008345 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008346#endif
8347#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008348 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008349#endif
8350#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008351 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008352#endif
8353#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008354 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008355#endif
8356#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008357 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008358#endif
8359#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008360 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008361#endif
8362#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008363 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008364#endif
8365#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008366 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008367#endif
8368#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008369 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008370#endif
8371#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008372 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008373#endif
8374#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008375 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008376#endif
8377#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008378 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008379#endif
8380#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008381 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008382#endif
8383#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008384 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008385#endif
8386#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008387 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008388#endif
8389#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008390 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008391#endif
Fred Draked86ed291999-12-15 15:34:33 +00008392#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008393 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008394#endif
Fred Drakec9680921999-12-13 16:37:25 +00008395#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008396 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008397#endif
8398#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008399 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008400#endif
8401#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008402 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008403#endif
8404#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008405 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008406#endif
8407#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008408 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008409#endif
8410#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008411 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008412#endif
8413#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008414 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008415#endif
8416#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008417 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008418#endif
8419#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008420 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008421#endif
8422#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008423 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008424#endif
8425#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008426 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008427#endif
8428#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008429 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008430#endif
8431#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008432 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008433#endif
8434#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008435 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008436#endif
8437#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008438 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008439#endif
8440#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008441 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008442#endif
8443#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008444 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008445#endif
8446#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008447 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008448#endif
8449#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008450 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008451#endif
8452#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008453 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008454#endif
8455#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008456 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008457#endif
8458#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008459 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008460#endif
8461#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008462 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008463#endif
8464#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008465 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008466#endif
8467#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008469#endif
8470#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008471 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008472#endif
8473#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008474 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008475#endif
8476#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008477 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008478#endif
8479#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008480 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008481#endif
8482#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008483 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008484#endif
8485#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008486 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008487#endif
8488#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008489 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008490#endif
8491#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008492 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008493#endif
8494#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008495 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008496#endif
8497#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008498 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008499#endif
8500#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008501 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008502#endif
8503#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008504 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008505#endif
8506#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008507 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008508#endif
8509#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008510 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008511#endif
8512#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008513 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008514#endif
8515#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008516 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008517#endif
8518#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008519 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008520#endif
8521#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008522 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008523#endif
8524#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008525 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008526#endif
8527#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008528 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008529#endif
8530};
8531
8532static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008533conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008534{
8535 return conv_confname(arg, valuep, posix_constants_sysconf,
8536 sizeof(posix_constants_sysconf)
8537 / sizeof(struct constdef));
8538}
8539
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008540PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008541"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008542Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008543
8544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008545posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008546{
8547 PyObject *result = NULL;
8548 int name;
8549
8550 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008551 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008552
Victor Stinner862490a2010-05-06 00:03:44 +00008553 errno = 0;
8554 value = sysconf(name);
8555 if (value == -1 && errno != 0)
8556 posix_error();
8557 else
8558 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008559 }
8560 return result;
8561}
8562#endif
8563
8564
Fred Drakebec628d1999-12-15 18:31:10 +00008565/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008566 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008567 * the exported dictionaries that are used to publish information about the
8568 * names available on the host platform.
8569 *
8570 * Sorting the table at runtime ensures that the table is properly ordered
8571 * when used, even for platforms we're not able to test on. It also makes
8572 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008573 */
Fred Drakebec628d1999-12-15 18:31:10 +00008574
8575static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008576cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008577{
8578 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008579 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008580 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008581 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008582
8583 return strcmp(c1->name, c2->name);
8584}
8585
8586static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008587setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008588 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008589{
Fred Drakebec628d1999-12-15 18:31:10 +00008590 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008591 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008592 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8593 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008594 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008595 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008596
Barry Warsaw3155db32000-04-13 15:20:40 +00008597 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008598 PyObject *o = PyInt_FromLong(table[i].value);
8599 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8600 Py_XDECREF(o);
8601 Py_DECREF(d);
8602 return -1;
8603 }
8604 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008605 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008606 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008607}
8608
Fred Drakebec628d1999-12-15 18:31:10 +00008609/* Return -1 on failure, 0 on success. */
8610static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008611setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008612{
8613#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008614 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008615 sizeof(posix_constants_pathconf)
8616 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008617 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008618 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008619#endif
8620#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008621 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008622 sizeof(posix_constants_confstr)
8623 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008624 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008625 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008626#endif
8627#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008628 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008629 sizeof(posix_constants_sysconf)
8630 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008631 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008632 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008633#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008634 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008635}
Fred Draked86ed291999-12-15 15:34:33 +00008636
8637
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008638PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008639"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008640Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008641in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008642
8643static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008644posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008645{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008646 abort();
8647 /*NOTREACHED*/
8648 Py_FatalError("abort() called from Python code didn't abort!");
8649 return NULL;
8650}
Fred Drakebec628d1999-12-15 18:31:10 +00008651
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008652#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008653PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008654"startfile(filepath [, operation]) - Start a file with its associated\n\
8655application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008656\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008657When \"operation\" is not specified or \"open\", this acts like\n\
8658double-clicking the file in Explorer, or giving the file name as an\n\
8659argument to the DOS \"start\" command: the file is opened with whatever\n\
8660application (if any) its extension is associated.\n\
8661When another \"operation\" is given, it specifies what should be done with\n\
8662the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008663\n\
8664startfile returns as soon as the associated application is launched.\n\
8665There is no option to wait for the application to close, and no way\n\
8666to retrieve the application's exit status.\n\
8667\n\
8668The filepath is relative to the current directory. If you want to use\n\
8669an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008670the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008671
8672static PyObject *
8673win32_startfile(PyObject *self, PyObject *args)
8674{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008675 char *filepath;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008676 Py_UNICODE *wpath;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008677 char *operation = NULL;
8678 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008679
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008680 PyObject *woperation = NULL;
8681 if (!PyArg_ParseTuple(args, "u|s:startfile",
8682 &wpath, &operation)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008683 PyErr_Clear();
8684 goto normal;
8685 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008686
Victor Stinnerd6f85422010-05-05 23:33:33 +00008687 if (operation) {
8688 woperation = PyUnicode_DecodeASCII(operation,
8689 strlen(operation), NULL);
8690 if (!woperation) {
8691 PyErr_Clear();
8692 operation = NULL;
8693 goto normal;
8694 }
8695 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008696
Victor Stinnerd6f85422010-05-05 23:33:33 +00008697 Py_BEGIN_ALLOW_THREADS
8698 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008699 wpath,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008700 NULL, NULL, SW_SHOWNORMAL);
8701 Py_END_ALLOW_THREADS
8702
8703 Py_XDECREF(woperation);
8704 if (rc <= (HINSTANCE)32) {
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008705 PyObject *errval = win32_error_unicode("startfile", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00008706 return errval;
8707 }
8708 Py_INCREF(Py_None);
8709 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008710
8711normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008712 if (!PyArg_ParseTuple(args, "et|s:startfile",
8713 Py_FileSystemDefaultEncoding, &filepath,
8714 &operation))
8715 return NULL;
8716 Py_BEGIN_ALLOW_THREADS
8717 rc = ShellExecute((HWND)0, operation, filepath,
8718 NULL, NULL, SW_SHOWNORMAL);
8719 Py_END_ALLOW_THREADS
8720 if (rc <= (HINSTANCE)32) {
8721 PyObject *errval = win32_error("startfile", filepath);
8722 PyMem_Free(filepath);
8723 return errval;
8724 }
8725 PyMem_Free(filepath);
8726 Py_INCREF(Py_None);
8727 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008728}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008729#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008730
Martin v. Löwis438b5342002-12-27 10:16:42 +00008731#ifdef HAVE_GETLOADAVG
8732PyDoc_STRVAR(posix_getloadavg__doc__,
8733"getloadavg() -> (float, float, float)\n\n\
8734Return the number of processes in the system run queue averaged over\n\
8735the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8736was unobtainable");
8737
8738static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008739posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008740{
8741 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008742 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008743 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8744 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008745 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008746 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008747}
8748#endif
8749
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008750PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008751"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008752Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008753
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008754static PyObject *
8755posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008756{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008757 Py_ssize_t size;
8758 PyObject *result;
8759 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008760
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008761 /* Read arguments */
8762 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008763 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008764 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008765 return PyErr_Format(PyExc_ValueError,
8766 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008767 result = PyBytes_FromStringAndSize(NULL, size);
8768 if (result == NULL)
8769 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008770
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008771 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8772 PyBytes_GET_SIZE(result));
8773 if (ret == -1) {
8774 Py_DECREF(result);
8775 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008776 }
8777 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008778}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008779
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008780#ifdef HAVE_SETRESUID
8781PyDoc_STRVAR(posix_setresuid__doc__,
8782"setresuid(ruid, euid, suid)\n\n\
8783Set the current process's real, effective, and saved user ids.");
8784
8785static PyObject*
8786posix_setresuid (PyObject *self, PyObject *args)
8787{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008788 uid_t ruid, euid, suid;
8789 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8790 _Py_Uid_Converter, &ruid,
8791 _Py_Uid_Converter, &euid,
8792 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008793 return NULL;
8794 if (setresuid(ruid, euid, suid) < 0)
8795 return posix_error();
8796 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008797}
8798#endif
8799
8800#ifdef HAVE_SETRESGID
8801PyDoc_STRVAR(posix_setresgid__doc__,
8802"setresgid(rgid, egid, sgid)\n\n\
8803Set the current process's real, effective, and saved group ids.");
8804
8805static PyObject*
8806posix_setresgid (PyObject *self, PyObject *args)
8807{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008808 gid_t rgid, egid, sgid;
8809 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8810 _Py_Gid_Converter, &rgid,
8811 _Py_Gid_Converter, &egid,
8812 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008813 return NULL;
8814 if (setresgid(rgid, egid, sgid) < 0)
8815 return posix_error();
8816 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008817}
8818#endif
8819
8820#ifdef HAVE_GETRESUID
8821PyDoc_STRVAR(posix_getresuid__doc__,
8822"getresuid() -> (ruid, euid, suid)\n\n\
8823Get tuple of the current process's real, effective, and saved user ids.");
8824
8825static PyObject*
8826posix_getresuid (PyObject *self, PyObject *noargs)
8827{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008828 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008829 if (getresuid(&ruid, &euid, &suid) < 0)
8830 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008831 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8832 _PyInt_FromUid(euid),
8833 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008834}
8835#endif
8836
8837#ifdef HAVE_GETRESGID
8838PyDoc_STRVAR(posix_getresgid__doc__,
8839"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008840Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008841
8842static PyObject*
8843posix_getresgid (PyObject *self, PyObject *noargs)
8844{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008845 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008846 if (getresgid(&rgid, &egid, &sgid) < 0)
8847 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008848 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8849 _PyInt_FromGid(egid),
8850 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008851}
8852#endif
8853
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008854static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008855 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008856#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008857 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008858#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008859 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008860#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008862#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008864#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008866#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008867#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008869#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008870#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008871 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008872#endif /* HAVE_LCHMOD */
8873#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008874 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008875#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008876#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008877 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008878#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008879#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008881#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008882#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008883 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008884#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008885#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008887#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008888#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008889 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008890#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008891 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008892#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008893#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008894#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008896#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008897 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8898 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8899 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008900#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008902#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008903#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008904 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008905#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008906 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8907 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8908 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8909 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008910#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008911 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008912#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008913#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008914 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008915#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008916 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008917#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008918 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008919#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008920 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8921 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8922 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008923#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008925#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008926 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008927#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008928 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8929 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008930#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008931#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8933 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008934#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8936 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008937#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008938#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008939#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008940 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008941#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008942#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008943 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008944#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008945#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008946 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008947#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008948#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008949 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008950#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008951#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008953#endif /* HAVE_GETEGID */
8954#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008955 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008956#endif /* HAVE_GETEUID */
8957#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008958 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008959#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008960#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008961 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008964#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008965 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008966#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008967#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008968 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008969#endif /* HAVE_GETPPID */
8970#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008971 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008972#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008973#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008974 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008975#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008976#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008977 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008978#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008979#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008980 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008981#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008982#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008983 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008984#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008985#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008986 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008987#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008988 {"popen2", win32_popen2, METH_VARARGS},
8989 {"popen3", win32_popen3, METH_VARARGS},
8990 {"popen4", win32_popen4, METH_VARARGS},
8991 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8992 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008993#else
8994#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008995 {"popen2", os2emx_popen2, METH_VARARGS},
8996 {"popen3", os2emx_popen3, METH_VARARGS},
8997 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008998#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008999#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009000#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009001#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009002 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009003#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009004#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009005 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009006#endif /* HAVE_SETEUID */
9007#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009008 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009009#endif /* HAVE_SETEGID */
9010#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009011 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009012#endif /* HAVE_SETREUID */
9013#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009014 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009015#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009016#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009017 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009018#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009019#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009020 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009021#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009022#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009023 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009024#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00009025#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009026 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00009027#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009028#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009029 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009030#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009031#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009032 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009033#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009034#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009035 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009036#endif /* HAVE_WAIT3 */
9037#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009038 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009039#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009040#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009041 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009042#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009043#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009044 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009045#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009046#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009047 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009048#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009049#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009050 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009051#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009052#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009053 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009054#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009055#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009056 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009057#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009059 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009060 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9061 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9062 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9063 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9064 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9065 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9066 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9067 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9068 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009069#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009070 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009071#endif
9072#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009073 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009074#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009075#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009076 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009077#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009078#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009079 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9080 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9081 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009082#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009083#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009084 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009085#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009086#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009087 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009088#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009089#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009090 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009091#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009092 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009093#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009094 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009095#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009096#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009098#endif
9099#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009101#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009102#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009103#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009104 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009105#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009106#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009107 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009108#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009109#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009110 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009111#endif /* WIFSTOPPED */
9112#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009113 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009114#endif /* WIFSIGNALED */
9115#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009117#endif /* WIFEXITED */
9118#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009119 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009120#endif /* WEXITSTATUS */
9121#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009122 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009123#endif /* WTERMSIG */
9124#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009126#endif /* WSTOPSIG */
9127#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009128#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009129 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009130#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009131#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009132 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009133#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009134#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009135 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009136#endif
9137#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009139#endif
9140#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009141 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009142#endif
Fred Drakec9680921999-12-13 16:37:25 +00009143#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009145#endif
9146#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009147 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009148#endif
9149#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009150 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
9152#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009153 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009154#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009155 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009156#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009157 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009158 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009159#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009160#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009161 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009162#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009163#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009164 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009165#endif
9166#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009167 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009168#endif
9169#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009170 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009171#endif
9172#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009173 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009174#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009175 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009176 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009177};
9178
9179
Barry Warsaw4a342091996-12-19 23:50:02 +00009180static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009181ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009182{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009183 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009184}
9185
Guido van Rossumd48f2521997-12-05 22:19:34 +00009186#if defined(PYOS_OS2)
9187/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009188static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009189{
9190 APIRET rc;
9191 ULONG values[QSV_MAX+1];
9192 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009193 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009194
9195 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009196 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009197 Py_END_ALLOW_THREADS
9198
9199 if (rc != NO_ERROR) {
9200 os2_error(rc);
9201 return -1;
9202 }
9203
Fred Drake4d1e64b2002-04-15 19:40:07 +00009204 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9205 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9206 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9207 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9208 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9209 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9210 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009211
9212 switch (values[QSV_VERSION_MINOR]) {
9213 case 0: ver = "2.00"; break;
9214 case 10: ver = "2.10"; break;
9215 case 11: ver = "2.11"; break;
9216 case 30: ver = "3.00"; break;
9217 case 40: ver = "4.00"; break;
9218 case 50: ver = "5.00"; break;
9219 default:
Tim Peters885d4572001-11-28 20:27:42 +00009220 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009221 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009222 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009223 ver = &tmp[0];
9224 }
9225
9226 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009227 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009228 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009229
9230 /* Add Indicator of Which Drive was Used to Boot the System */
9231 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9232 tmp[1] = ':';
9233 tmp[2] = '\0';
9234
Fred Drake4d1e64b2002-04-15 19:40:07 +00009235 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009236}
9237#endif
9238
Barry Warsaw4a342091996-12-19 23:50:02 +00009239static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009240all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009241{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009242#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009243 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009244#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009245#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009246 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009247#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009248#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009249 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009250#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009251#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009253#endif
Fred Drakec9680921999-12-13 16:37:25 +00009254#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009255 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009256#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009257#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009258 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009259#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009260#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009262#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009263#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009264 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009265#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009266#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009267 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009268#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009269#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009270 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009271#endif
9272#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009273 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009274#endif
9275#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009276 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009277#endif
9278#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009279 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009280#endif
9281#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009282 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009283#endif
9284#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009285 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009286#endif
9287#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009288 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009289#endif
9290#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009291 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009292#endif
9293#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009294 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009295#endif
9296#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009297 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009298#endif
9299#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009300 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009301#endif
9302#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009303 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009304#endif
9305#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009306 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009307#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009308#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009309 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009310#endif
9311#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009312 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009313#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009314#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009315 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009316#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009317#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009318 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009319#endif
9320#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009321 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009322#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009323
Tim Peters5aa91602002-01-30 05:46:57 +00009324/* MS Windows */
9325#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009326 /* Don't inherit in child processes. */
9327 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009328#endif
9329#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 /* Optimize for short life (keep in memory). */
9331 /* MS forgot to define this one with a non-underscore form too. */
9332 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009333#endif
9334#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009335 /* Automatically delete when last handle is closed. */
9336 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009337#endif
9338#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 /* Optimize for random access. */
9340 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009341#endif
9342#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009343 /* Optimize for sequential access. */
9344 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009345#endif
9346
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009347/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009348#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009349 /* Send a SIGIO signal whenever input or output
9350 becomes available on file descriptor */
9351 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009352#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009353#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009354 /* Direct disk access. */
9355 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009356#endif
9357#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009358 /* Must be a directory. */
9359 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009360#endif
9361#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009362 /* Do not follow links. */
9363 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009364#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009365#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009366 /* Do not update the access time. */
9367 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009368#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009369
Victor Stinnerd6f85422010-05-05 23:33:33 +00009370 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009371#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009372 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009373#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009374#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009375 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009376#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009377#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009378 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009379#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009380#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009381 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009382#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009383#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009384 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009385#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009386#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009387 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009388#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009389#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009390 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009391#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009392#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009393 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009394#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009395#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009396 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009397#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009398#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009399 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009400#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009401#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009402 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009403#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009404#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009405 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009406#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009407#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009408 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009409#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009410#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009411 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009412#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009413#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009414 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009415#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009416#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009417 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009418#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009419#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009420 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009421#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009422
Guido van Rossum246bc171999-02-01 23:54:31 +00009423#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009424#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009425 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9426 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9427 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9428 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9429 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9430 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9431 if (ins(d, "P_PM", (long)P_PM)) return -1;
9432 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9433 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9434 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9435 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9436 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9437 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9438 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9439 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9440 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9441 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9442 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9443 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9444 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009445#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009446 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9447 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9448 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9449 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9450 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009451#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009452#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009453
Guido van Rossumd48f2521997-12-05 22:19:34 +00009454#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009455 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009456#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009457 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009458}
9459
9460
Tim Peters5aa91602002-01-30 05:46:57 +00009461#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009462#define INITFUNC initnt
9463#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009464
9465#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009466#define INITFUNC initos2
9467#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009468
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009469#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009470#define INITFUNC initposix
9471#define MODNAME "posix"
9472#endif
9473
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009474PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009475INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009476{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009477 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009478
Victor Stinnerd6f85422010-05-05 23:33:33 +00009479 m = Py_InitModule3(MODNAME,
9480 posix_methods,
9481 posix__doc__);
9482 if (m == NULL)
9483 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009484
Victor Stinnerd6f85422010-05-05 23:33:33 +00009485 /* Initialize environ dictionary */
9486 v = convertenviron();
9487 Py_XINCREF(v);
9488 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9489 return;
9490 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009491
Victor Stinnerd6f85422010-05-05 23:33:33 +00009492 if (all_ins(m))
9493 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009494
Victor Stinnerd6f85422010-05-05 23:33:33 +00009495 if (setup_confname_tables(m))
9496 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009497
Victor Stinnerd6f85422010-05-05 23:33:33 +00009498 Py_INCREF(PyExc_OSError);
9499 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009500
Guido van Rossumb3d39562000-01-31 18:41:26 +00009501#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009502 if (posix_putenv_garbage == NULL)
9503 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009504#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009505
Victor Stinnerd6f85422010-05-05 23:33:33 +00009506 if (!initialized) {
9507 stat_result_desc.name = MODNAME ".stat_result";
9508 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9509 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9510 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9511 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9512 structseq_new = StatResultType.tp_new;
9513 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009514
Victor Stinnerd6f85422010-05-05 23:33:33 +00009515 statvfs_result_desc.name = MODNAME ".statvfs_result";
9516 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009517#ifdef NEED_TICKS_PER_SECOND
9518# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009519 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009520# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009521 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009522# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009523 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009524# endif
9525#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009526 }
9527 Py_INCREF((PyObject*) &StatResultType);
9528 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9529 Py_INCREF((PyObject*) &StatVFSResultType);
9530 PyModule_AddObject(m, "statvfs_result",
9531 (PyObject*) &StatVFSResultType);
9532 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009533
9534#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009535 /*
9536 * Step 2 of weak-linking support on Mac OS X.
9537 *
9538 * The code below removes functions that are not available on the
9539 * currently active platform.
9540 *
9541 * This block allow one to use a python binary that was build on
9542 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9543 * OSX 10.4.
9544 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009545#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009546 if (fstatvfs == NULL) {
9547 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9548 return;
9549 }
9550 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009551#endif /* HAVE_FSTATVFS */
9552
9553#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009554 if (statvfs == NULL) {
9555 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9556 return;
9557 }
9558 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009559#endif /* HAVE_STATVFS */
9560
9561# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009562 if (lchown == NULL) {
9563 if (PyObject_DelAttrString(m, "lchown") == -1) {
9564 return;
9565 }
9566 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009567#endif /* HAVE_LCHOWN */
9568
9569
9570#endif /* __APPLE__ */
9571
Guido van Rossumb6775db1994-08-01 11:34:53 +00009572}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009573
9574#ifdef __cplusplus
9575}
9576#endif
9577
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009578