blob: cecbb45fb4b3672a1411c8e9f2dc42737f1079d4 [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
Christian Heimesffa70112017-09-05 17:08:45 +020068#ifdef HAVE_SYS_SYSMACROS_H
69/* GNU C Library: major(), minor(), makedev() */
70#include <sys/sysmacros.h>
71#endif
72
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000075#endif /* HAVE_SYS_TYPES_H */
76
77#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000078#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080
Guido van Rossum36bc6801995-06-14 22:54:23 +000081#ifdef HAVE_SYS_WAIT_H
Victor Stinnerd6f85422010-05-05 23:33:33 +000082#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000083#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000084
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000085#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000086#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000087#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000088
Guido van Rossumb6775db1994-08-01 11:34:53 +000089#ifdef HAVE_FCNTL_H
90#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000091#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000092
Guido van Rossuma6535fd2001-10-18 19:44:10 +000093#ifdef HAVE_GRP_H
94#include <grp.h>
95#endif
96
Barry Warsaw5676bd12003-01-07 20:57:09 +000097#ifdef HAVE_SYSEXITS_H
98#include <sysexits.h>
99#endif /* HAVE_SYSEXITS_H */
100
Anthony Baxter8a560de2004-10-13 15:30:56 +0000101#ifdef HAVE_SYS_LOADAVG_H
102#include <sys/loadavg.h>
103#endif
104
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000106/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000107#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000108#include <process.h>
109#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000110#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#define HAVE_GETCWD 1
112#define HAVE_OPENDIR 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000113#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#if defined(__OS2__)
115#define HAVE_EXECV 1
116#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000117#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#include <process.h>
119#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000120#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000121#define HAVE_EXECV 1
122#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#define HAVE_OPENDIR 1
124#define HAVE_PIPE 1
125#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000126#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#define HAVE_WAIT 1
128#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000129#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000130#define HAVE_GETCWD 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000131#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000132#define HAVE_EXECV 1
133#define HAVE_PIPE 1
134#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000135#define HAVE_SYSTEM 1
136#define HAVE_CWAIT 1
137#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000138#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000139#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000140#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
141/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinnerd6f85422010-05-05 23:33:33 +0000142#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143/* Unix functions that the configure script doesn't check for */
144#define HAVE_EXECV 1
145#define HAVE_FORK 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000146#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000147#define HAVE_FORK1 1
148#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#define HAVE_GETCWD 1
150#define HAVE_GETEGID 1
151#define HAVE_GETEUID 1
152#define HAVE_GETGID 1
153#define HAVE_GETPPID 1
154#define HAVE_GETUID 1
155#define HAVE_KILL 1
156#define HAVE_OPENDIR 1
157#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000158#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000160#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000161#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#define HAVE_WAIT 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000163#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000164#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000165#endif /* _MSC_VER */
166#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000167#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000172#if defined(__sgi)&&_COMPILER_VERSION>=700
173/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
174 (default) */
175extern char *ctermid_r(char *);
176#endif
177
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000178#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000179#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000182#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000184#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000185extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000187#endif
188#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000189extern int chdir(char *);
190extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chdir(const char *);
193extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000195#ifdef __BORLANDC__
196extern int chmod(const char *, int);
197#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000199#endif
Christian Heimes36281872007-11-30 21:11:28 +0000200/*#ifdef HAVE_FCHMOD
201extern int fchmod(int, mode_t);
202#endif*/
203/*#ifdef HAVE_LCHMOD
204extern int lchmod(const char *, mode_t);
205#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int chown(const char *, uid_t, gid_t);
207extern char *getcwd(char *, int);
208extern char *strerror(int);
209extern int link(const char *, const char *);
210extern int rename(const char *, const char *);
211extern int stat(const char *, struct stat *);
212extern int unlink(const char *);
213extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000216#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000219#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000221
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000222#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#ifdef HAVE_UTIME_H
225#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000226#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000228#ifdef HAVE_SYS_UTIME_H
229#include <sys/utime.h>
230#define HAVE_UTIME_H /* pretend we do for the rest of this file */
231#endif /* HAVE_SYS_UTIME_H */
232
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#ifdef HAVE_SYS_TIMES_H
234#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236
237#ifdef HAVE_SYS_PARAM_H
238#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000239#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240
241#ifdef HAVE_SYS_UTSNAME_H
242#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000243#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000247#define NAMLEN(dirent) strlen((dirent)->d_name)
248#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000249#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000250#include <direct.h>
251#define NAMLEN(dirent) strlen((dirent)->d_name)
252#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000254#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#endif
259#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000261#endif
262#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#endif
265#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000267#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000268#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000270#endif
271#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000273#endif
274#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000276#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000277#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000278#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <windows.h>
Victor Stinnerd6f85422010-05-05 23:33:33 +0000280#include <shellapi.h> /* for ShellExecute() */
281#define popen _popen
282#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000283#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossumd48f2521997-12-05 22:19:34 +0000285#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000286#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000287#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000290#if defined(PATH_MAX) && PATH_MAX > 1024
291#define MAXPATHLEN PATH_MAX
292#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000293#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000294#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000295#endif /* MAXPATHLEN */
296
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000297#ifdef UNION_WAIT
298/* Emulate some macros on systems that have a union instead of macros */
299
300#ifndef WIFEXITED
301#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
302#endif
303
304#ifndef WEXITSTATUS
305#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
306#endif
307
308#ifndef WTERMSIG
309#define WTERMSIG(u_wait) ((u_wait).w_termsig)
310#endif
311
Neal Norwitzd5a37542006-03-20 06:48:34 +0000312#define WAIT_TYPE union wait
313#define WAIT_STATUS_INT(s) (s.w_status)
314
315#else /* !UNION_WAIT */
316#define WAIT_TYPE int
317#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000318#endif /* UNION_WAIT */
319
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000320/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000321#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000322#define PARSE_PID "i"
323#define PyLong_FromPid PyInt_FromLong
324#define PyLong_AsPid PyInt_AsLong
325#elif SIZEOF_PID_T == SIZEOF_LONG
326#define PARSE_PID "l"
327#define PyLong_FromPid PyInt_FromLong
328#define PyLong_AsPid PyInt_AsLong
329#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
330#define PARSE_PID "L"
331#define PyLong_FromPid PyLong_FromLongLong
332#define PyLong_AsPid PyInt_AsLongLong
333#else
334#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000335#endif /* SIZEOF_PID_T */
336
Greg Wardb48bc172000-03-01 21:51:56 +0000337/* Don't use the "_r" form if we don't need it (also, won't have a
338 prototype for it, at least on Solaris -- maybe others as well?). */
339#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
340#define USE_CTERMID_R
341#endif
342
343#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
344#define USE_TMPNAM_R
345#endif
346
Tim Peters11b23062003-04-23 02:39:17 +0000347#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000348#include <sys/mkdev.h>
349#else
350#if defined(MAJOR_IN_SYSMACROS)
351#include <sys/sysmacros.h>
352#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000353#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
354#include <sys/mkdev.h>
355#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000356#endif
Fred Drake699f3522000-06-29 21:12:41 +0000357
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200358
359#ifndef MS_WINDOWS
360PyObject *
361_PyInt_FromUid(uid_t uid)
362{
363 if (uid <= LONG_MAX)
364 return PyInt_FromLong(uid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500365 return PyLong_FromUnsignedLong(uid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200366}
367
368PyObject *
369_PyInt_FromGid(gid_t gid)
370{
371 if (gid <= LONG_MAX)
372 return PyInt_FromLong(gid);
Benjamin Peterson4d7fc3c2013-03-23 15:35:24 -0500373 return PyLong_FromUnsignedLong(gid);
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200374}
375
376int
377_Py_Uid_Converter(PyObject *obj, void *p)
378{
379 int overflow;
380 long result;
381 if (PyFloat_Check(obj)) {
382 PyErr_SetString(PyExc_TypeError,
383 "integer argument expected, got float");
384 return 0;
385 }
386 result = PyLong_AsLongAndOverflow(obj, &overflow);
387 if (overflow < 0)
388 goto OverflowDown;
389 if (!overflow && result == -1) {
390 /* error or -1 */
391 if (PyErr_Occurred())
392 return 0;
393 *(uid_t *)p = (uid_t)-1;
394 }
395 else {
396 /* unsigned uid_t */
397 unsigned long uresult;
398 if (overflow > 0) {
399 uresult = PyLong_AsUnsignedLong(obj);
400 if (PyErr_Occurred()) {
401 if (PyErr_ExceptionMatches(PyExc_OverflowError))
402 goto OverflowUp;
403 return 0;
404 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200405 } else {
406 if (result < 0)
407 goto OverflowDown;
408 uresult = result;
409 }
410 if (sizeof(uid_t) < sizeof(long) &&
411 (unsigned long)(uid_t)uresult != uresult)
412 goto OverflowUp;
413 *(uid_t *)p = (uid_t)uresult;
414 }
415 return 1;
416
417OverflowDown:
418 PyErr_SetString(PyExc_OverflowError,
419 "user id is less than minimum");
420 return 0;
421
422OverflowUp:
423 PyErr_SetString(PyExc_OverflowError,
424 "user id is greater than maximum");
425 return 0;
426}
427
428int
429_Py_Gid_Converter(PyObject *obj, void *p)
430{
431 int overflow;
432 long result;
433 if (PyFloat_Check(obj)) {
434 PyErr_SetString(PyExc_TypeError,
435 "integer argument expected, got float");
436 return 0;
437 }
438 result = PyLong_AsLongAndOverflow(obj, &overflow);
439 if (overflow < 0)
440 goto OverflowDown;
441 if (!overflow && result == -1) {
442 /* error or -1 */
443 if (PyErr_Occurred())
444 return 0;
445 *(gid_t *)p = (gid_t)-1;
446 }
447 else {
448 /* unsigned gid_t */
449 unsigned long uresult;
450 if (overflow > 0) {
451 uresult = PyLong_AsUnsignedLong(obj);
452 if (PyErr_Occurred()) {
453 if (PyErr_ExceptionMatches(PyExc_OverflowError))
454 goto OverflowUp;
455 return 0;
456 }
Serhiy Storchakada5c2a02013-02-12 09:27:53 +0200457 } else {
458 if (result < 0)
459 goto OverflowDown;
460 uresult = result;
461 }
462 if (sizeof(gid_t) < sizeof(long) &&
463 (unsigned long)(gid_t)uresult != uresult)
464 goto OverflowUp;
465 *(gid_t *)p = (gid_t)uresult;
466 }
467 return 1;
468
469OverflowDown:
470 PyErr_SetString(PyExc_OverflowError,
471 "group id is less than minimum");
472 return 0;
473
474OverflowUp:
475 PyErr_SetString(PyExc_OverflowError,
476 "group id is greater than maximum");
477 return 0;
478}
479#endif /* MS_WINDOWS */
480
481
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200482#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
483static int
484_Py_Dev_Converter(PyObject *obj, void *p)
485{
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300486 PyObject *index = PyNumber_Index(obj);
487 if (index == NULL)
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200488 return 0;
Serhiy Storchaka9aa16d92015-04-20 09:21:23 +0300489 if (PyInt_Check(index)) {
490 long x = PyInt_AS_LONG(index);
491 Py_DECREF(index);
492 if (x == -1 && PyErr_Occurred())
493 return 0;
494 if (x < 0) {
495 PyErr_SetString(PyExc_OverflowError,
496 "can't convert negative number to unsigned long");
497 return 0;
498 }
499 *((dev_t *)p) = (unsigned long)x;
500 }
501 else if (PyLong_Check(index)) {
502#ifdef HAVE_LONG_LONG
503 *((dev_t *)p) = PyLong_AsUnsignedLongLong(index);
504#else
505 *((dev_t *)p) = PyLong_AsUnsignedLong(index);
506#endif
507 Py_DECREF(index);
508 if (PyErr_Occurred())
509 return 0;
510 }
511 else {
512 Py_DECREF(index);
513 PyErr_Format(PyExc_TypeError,
514 "expected int/long, %s found",
515 Py_TYPE(obj)->tp_name);
516 return 0;
517 }
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200518 return 1;
519}
520
Serhiy Storchakabe8c6ae2015-07-12 16:41:29 +0300521#endif
522
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200523#ifdef HAVE_LONG_LONG
524static PyObject *
525_PyInt_FromDev(PY_LONG_LONG v)
526{
527 if (LONG_MIN <= v && v <= LONG_MAX)
528 return PyInt_FromLong((long)v);
529 else
530 return PyLong_FromLongLong(v);
531}
532#else
533# define _PyInt_FromDev PyInt_FromLong
534#endif
535
Serhiy Storchaka2098d612015-01-18 11:11:25 +0200536
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000537#if defined _MSC_VER && _MSC_VER >= 1400
538/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
Andrew Svetlov4bb142b2012-12-18 21:27:37 +0200539 * valid and raise an assertion if it isn't.
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000540 * Normally, an invalid fd is likely to be a C program error and therefore
541 * an assertion can be useful, but it does contradict the POSIX standard
542 * which for write(2) states:
543 * "Otherwise, -1 shall be returned and errno set to indicate the error."
544 * "[EBADF] The fildes argument is not a valid file descriptor open for
545 * writing."
546 * Furthermore, python allows the user to enter any old integer
547 * as a fd and should merely raise a python exception on error.
548 * The Microsoft CRT doesn't provide an official way to check for the
549 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000550 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000551 * internal structures involved.
552 * The structures below must be updated for each version of visual studio
553 * according to the file internal.h in the CRT source, until MS comes
554 * up with a less hacky way to do this.
555 * (all of this is to avoid globally modifying the CRT behaviour using
556 * _set_invalid_parameter_handler() and _CrtSetReportMode())
557 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000558/* The actual size of the structure is determined at runtime.
559 * Only the first items must be present.
560 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000561typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000562 intptr_t osfhnd;
563 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000564} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000565
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000566extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000567#define IOINFO_L2E 5
568#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
569#define IOINFO_ARRAYS 64
570#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
571#define FOPEN 0x01
572#define _NO_CONSOLE_FILENO (intptr_t)-2
573
574/* This function emulates what the windows CRT does to validate file handles */
575int
576_PyVerify_fd(int fd)
577{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000578 const int i1 = fd >> IOINFO_L2E;
579 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000580
Victor Stinnerd6f85422010-05-05 23:33:33 +0000581 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000582
Victor Stinnerd6f85422010-05-05 23:33:33 +0000583 /* Determine the actual size of the ioinfo structure,
584 * as used by the CRT loaded in memory
585 */
586 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
587 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
588 }
589 if (sizeof_ioinfo == 0) {
590 /* This should not happen... */
591 goto fail;
592 }
593
594 /* See that it isn't a special CLEAR fileno */
595 if (fd != _NO_CONSOLE_FILENO) {
596 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
597 * we check pointer validity and other info
598 */
599 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
600 /* finally, check that the file is open */
601 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
602 if (info->osfile & FOPEN) {
603 return 1;
604 }
605 }
606 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000607 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000608 errno = EBADF;
609 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000610}
611
612/* the special case of checking dup2. The target fd must be in a sensible range */
613static int
614_PyVerify_fd_dup2(int fd1, int fd2)
615{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000616 if (!_PyVerify_fd(fd1))
617 return 0;
618 if (fd2 == _NO_CONSOLE_FILENO)
619 return 0;
620 if ((unsigned)fd2 < _NHANDLE_)
621 return 1;
622 else
623 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000624}
625#else
626/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
627#define _PyVerify_fd_dup2(A, B) (1)
628#endif
629
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000630/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100631#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +0000632/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100633** environ directly, we must obtain it with _NSGetEnviron(). See also
634** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +0000635*/
636#include <crt_externs.h>
637static char **environ;
638#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000639extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000640#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000641
Barry Warsaw53699e91996-12-10 23:23:01 +0000642static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000643convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000644{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000645 PyObject *d;
646 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000647#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000648 APIRET rc;
649 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
650#endif
651 d = PyDict_New();
652 if (d == NULL)
653 return NULL;
Ronald Oussoren1c60c7a2013-01-25 17:55:39 +0100654#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinnerd6f85422010-05-05 23:33:33 +0000655 if (environ == NULL)
656 environ = *_NSGetEnviron();
657#endif
658 if (environ == NULL)
659 return d;
660 /* This part ignores errors */
661 for (e = environ; *e != NULL; e++) {
662 PyObject *k;
663 PyObject *v;
664 char *p = strchr(*e, '=');
665 if (p == NULL)
666 continue;
667 k = PyString_FromStringAndSize(*e, (int)(p-*e));
668 if (k == NULL) {
669 PyErr_Clear();
670 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000671 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000672 v = PyString_FromString(p+1);
673 if (v == NULL) {
674 PyErr_Clear();
675 Py_DECREF(k);
676 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000677 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000678 if (PyDict_GetItem(d, k) == NULL) {
679 if (PyDict_SetItem(d, k, v) != 0)
680 PyErr_Clear();
681 }
682 Py_DECREF(k);
683 Py_DECREF(v);
684 }
685#if defined(PYOS_OS2)
686 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
687 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
688 PyObject *v = PyString_FromString(buffer);
689 PyDict_SetItemString(d, "BEGINLIBPATH", v);
690 Py_DECREF(v);
691 }
692 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
693 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
694 PyObject *v = PyString_FromString(buffer);
695 PyDict_SetItemString(d, "ENDLIBPATH", v);
696 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000697 }
698#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000699 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700}
701
702
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703/* Set a POSIX-specific error from errno, and return NULL */
704
Barry Warsawd58d7641998-07-23 16:14:40 +0000705static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000706posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000707{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000708 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000709}
Barry Warsawd58d7641998-07-23 16:14:40 +0000710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000711posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000712{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000713 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000714}
715
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000716#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000717static PyObject *
718posix_error_with_unicode_filename(Py_UNICODE* name)
719{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000720 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000721}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000722#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000723
724
Mark Hammondef8b6542001-05-13 08:04:26 +0000725static PyObject *
726posix_error_with_allocated_filename(char* name)
727{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000728 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
729 PyMem_Free(name);
730 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000731}
732
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000733#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000734static PyObject *
735win32_error(char* function, char* filename)
736{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000737 /* XXX We should pass the function name along in the future.
738 (_winreg.c also wants to pass the function name.)
739 This would however require an additional param to the
740 Windows error object, which is non-trivial.
741 */
742 errno = GetLastError();
743 if (filename)
744 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
745 else
746 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000747}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000748
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000749static PyObject *
750win32_error_unicode(char* function, Py_UNICODE* filename)
751{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000752 /* XXX - see win32_error for comments on 'function' */
753 errno = GetLastError();
754 if (filename)
755 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
756 else
757 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000758}
759
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000760static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000761convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000762{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000763 if (PyUnicode_CheckExact(*param))
764 Py_INCREF(*param);
765 else if (PyUnicode_Check(*param))
766 /* For a Unicode subtype that's not a Unicode object,
767 return a true Unicode object with the same data. */
768 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
769 PyUnicode_GET_SIZE(*param));
770 else
771 *param = PyUnicode_FromEncodedObject(*param,
772 Py_FileSystemDefaultEncoding,
773 "strict");
774 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000775}
776
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000777#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778
Guido van Rossumd48f2521997-12-05 22:19:34 +0000779#if defined(PYOS_OS2)
780/**********************************************************************
781 * Helper Function to Trim and Format OS/2 Messages
782 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000783static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000784os2_formatmsg(char *msgbuf, int msglen, char *reason)
785{
786 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
787
788 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000789 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000790
Victor Stinner862490a2010-05-06 00:03:44 +0000791 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
792 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000793 }
794
795 /* Add Optional Reason Text */
796 if (reason) {
797 strcat(msgbuf, " : ");
798 strcat(msgbuf, reason);
799 }
800}
801
802/**********************************************************************
803 * Decode an OS/2 Operating System Error Code
804 *
805 * A convenience function to lookup an OS/2 error code and return a
806 * text message we can use to raise a Python exception.
807 *
808 * Notes:
809 * The messages for errors returned from the OS/2 kernel reside in
810 * the file OSO001.MSG in the \OS2 directory hierarchy.
811 *
812 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000813static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000814os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
815{
816 APIRET rc;
817 ULONG msglen;
818
819 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
820 Py_BEGIN_ALLOW_THREADS
821 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
822 errorcode, "oso001.msg", &msglen);
823 Py_END_ALLOW_THREADS
824
825 if (rc == NO_ERROR)
826 os2_formatmsg(msgbuf, msglen, reason);
827 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000828 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000829 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000830
831 return msgbuf;
832}
833
834/* Set an OS/2-specific error and return NULL. OS/2 kernel
835 errors are not in a global variable e.g. 'errno' nor are
836 they congruent with posix error numbers. */
837
Victor Stinnerd6f85422010-05-05 23:33:33 +0000838static PyObject *
839os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000840{
841 char text[1024];
842 PyObject *v;
843
844 os2_strerror(text, sizeof(text), code, "");
845
846 v = Py_BuildValue("(is)", code, text);
847 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000848 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000849 Py_DECREF(v);
850 }
851 return NULL; /* Signal to Python that an Exception is Pending */
852}
853
854#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000855
856/* POSIX generic methods */
857
Barry Warsaw53699e91996-12-10 23:23:01 +0000858static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000859posix_fildes(PyObject *fdobj, int (*func)(int))
860{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000861 int fd;
862 int res;
863 fd = PyObject_AsFileDescriptor(fdobj);
864 if (fd < 0)
865 return NULL;
866 if (!_PyVerify_fd(fd))
867 return posix_error();
868 Py_BEGIN_ALLOW_THREADS
869 res = (*func)(fd);
870 Py_END_ALLOW_THREADS
871 if (res < 0)
872 return posix_error();
873 Py_INCREF(Py_None);
874 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000875}
Guido van Rossum21142a01999-01-08 21:05:37 +0000876
877static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000878posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000879{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000880 char *path1 = NULL;
881 int res;
882 if (!PyArg_ParseTuple(args, format,
883 Py_FileSystemDefaultEncoding, &path1))
884 return NULL;
885 Py_BEGIN_ALLOW_THREADS
886 res = (*func)(path1);
887 Py_END_ALLOW_THREADS
888 if (res < 0)
889 return posix_error_with_allocated_filename(path1);
890 PyMem_Free(path1);
891 Py_INCREF(Py_None);
892 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000893}
894
Barry Warsaw53699e91996-12-10 23:23:01 +0000895static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000896posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000897 char *format,
898 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000899{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000900 char *path1 = NULL, *path2 = NULL;
901 int res;
902 if (!PyArg_ParseTuple(args, format,
903 Py_FileSystemDefaultEncoding, &path1,
904 Py_FileSystemDefaultEncoding, &path2))
905 return NULL;
906 Py_BEGIN_ALLOW_THREADS
907 res = (*func)(path1, path2);
908 Py_END_ALLOW_THREADS
909 PyMem_Free(path1);
910 PyMem_Free(path2);
911 if (res != 0)
912 /* XXX how to report both path1 and path2??? */
913 return posix_error();
914 Py_INCREF(Py_None);
915 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000916}
917
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000918#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000919static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000920win32_1str(PyObject* args, char* func,
921 char* format, BOOL (__stdcall *funcA)(LPCSTR),
922 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000923{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000924 PyObject *uni;
925 char *ansi;
926 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000927
Victor Stinnerd6f85422010-05-05 23:33:33 +0000928 if (!PyArg_ParseTuple(args, wformat, &uni))
929 PyErr_Clear();
930 else {
931 Py_BEGIN_ALLOW_THREADS
932 result = funcW(PyUnicode_AsUnicode(uni));
933 Py_END_ALLOW_THREADS
934 if (!result)
935 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
936 Py_INCREF(Py_None);
937 return Py_None;
938 }
939 if (!PyArg_ParseTuple(args, format, &ansi))
940 return NULL;
941 Py_BEGIN_ALLOW_THREADS
942 result = funcA(ansi);
943 Py_END_ALLOW_THREADS
944 if (!result)
945 return win32_error(func, ansi);
946 Py_INCREF(Py_None);
947 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000948
949}
950
951/* This is a reimplementation of the C library's chdir function,
952 but one that produces Win32 errors instead of DOS error codes.
953 chdir is essentially a wrapper around SetCurrentDirectory; however,
954 it also needs to set "magic" environment variables indicating
955 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000956static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000957win32_chdir(LPCSTR path)
958{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000959 char new_path[MAX_PATH+1];
960 int result;
961 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000962
Victor Stinnerd6f85422010-05-05 23:33:33 +0000963 if(!SetCurrentDirectoryA(path))
964 return FALSE;
965 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
966 if (!result)
967 return FALSE;
968 /* In the ANSI API, there should not be any paths longer
969 than MAX_PATH. */
970 assert(result <= MAX_PATH+1);
971 if (strncmp(new_path, "\\\\", 2) == 0 ||
972 strncmp(new_path, "//", 2) == 0)
973 /* UNC path, nothing to do. */
974 return TRUE;
975 env[1] = new_path[0];
976 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000977}
978
979/* The Unicode version differs from the ANSI version
980 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000981static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000982win32_wchdir(LPCWSTR path)
983{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000984 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
985 int result;
986 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000987
Victor Stinnerd6f85422010-05-05 23:33:33 +0000988 if(!SetCurrentDirectoryW(path))
989 return FALSE;
990 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
991 if (!result)
992 return FALSE;
993 if (result > MAX_PATH+1) {
994 new_path = malloc(result * sizeof(wchar_t));
995 if (!new_path) {
996 SetLastError(ERROR_OUTOFMEMORY);
997 return FALSE;
998 }
999 result = GetCurrentDirectoryW(result, new_path);
1000 if (!result) {
1001 free(new_path);
1002 return FALSE;
1003 }
1004 }
1005 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1006 wcsncmp(new_path, L"//", 2) == 0)
1007 /* UNC path, nothing to do. */
1008 return TRUE;
1009 env[1] = new_path[0];
1010 result = SetEnvironmentVariableW(env, new_path);
1011 if (new_path != _new_path)
1012 free(new_path);
1013 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001014}
1015#endif
1016
Antoine Pitrouff48c0a2011-07-01 22:56:03 +02001017/* choose the appropriate stat and fstat functions and return structs */
1018#undef STAT
1019#undef FSTAT
1020#undef STRUCT_STAT
1021#if defined(MS_WIN64) || defined(MS_WINDOWS)
1022# define STAT win32_stat
1023# define FSTAT win32_fstat
1024# define STRUCT_STAT struct win32_stat
1025#else
1026# define STAT stat
1027# define FSTAT fstat
1028# define STRUCT_STAT struct stat
1029#endif
1030
Martin v. Löwis14694662006-02-03 12:54:16 +00001031#ifdef MS_WINDOWS
1032/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1033 - time stamps are restricted to second resolution
1034 - file modification times suffer from forth-and-back conversions between
1035 UTC and local time
1036 Therefore, we implement our own stat, based on the Win32 API directly.
1037*/
Victor Stinnerd6f85422010-05-05 23:33:33 +00001038#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001039
1040struct win32_stat{
1041 int st_dev;
1042 __int64 st_ino;
1043 unsigned short st_mode;
1044 int st_nlink;
1045 int st_uid;
1046 int st_gid;
1047 int st_rdev;
1048 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001049 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001050 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001051 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001052 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001053 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001054 int st_ctime_nsec;
1055};
1056
1057static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1058
1059static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001060FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001061{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001062 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1063 /* Cannot simply cast and dereference in_ptr,
1064 since it might not be aligned properly */
1065 __int64 in;
1066 memcpy(&in, in_ptr, sizeof(in));
1067 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001068 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001069}
1070
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001071static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001072time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001073{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001074 /* XXX endianness */
1075 __int64 out;
1076 out = time_in + secs_between_epochs;
1077 out = out * 10000000 + nsec_in / 100;
1078 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001079}
1080
Martin v. Löwis14694662006-02-03 12:54:16 +00001081/* Below, we *know* that ugo+r is 0444 */
1082#if _S_IREAD != 0400
1083#error Unsupported C library
1084#endif
1085static int
1086attributes_to_mode(DWORD attr)
1087{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001088 int m = 0;
1089 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1090 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1091 else
1092 m |= _S_IFREG;
1093 if (attr & FILE_ATTRIBUTE_READONLY)
1094 m |= 0444;
1095 else
1096 m |= 0666;
1097 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001098}
1099
1100static int
1101attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
1102{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001103 memset(result, 0, sizeof(*result));
1104 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1105 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1106 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1107 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1108 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001109
Victor Stinnerd6f85422010-05-05 23:33:33 +00001110 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001111}
1112
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001113static BOOL
1114attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1115{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001116 HANDLE hFindFile;
1117 WIN32_FIND_DATAA FileData;
1118 hFindFile = FindFirstFileA(pszFile, &FileData);
1119 if (hFindFile == INVALID_HANDLE_VALUE)
1120 return FALSE;
1121 FindClose(hFindFile);
1122 pfad->dwFileAttributes = FileData.dwFileAttributes;
1123 pfad->ftCreationTime = FileData.ftCreationTime;
1124 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1125 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1126 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1127 pfad->nFileSizeLow = FileData.nFileSizeLow;
1128 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001129}
1130
1131static BOOL
1132attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1133{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001134 HANDLE hFindFile;
1135 WIN32_FIND_DATAW FileData;
1136 hFindFile = FindFirstFileW(pszFile, &FileData);
1137 if (hFindFile == INVALID_HANDLE_VALUE)
1138 return FALSE;
1139 FindClose(hFindFile);
1140 pfad->dwFileAttributes = FileData.dwFileAttributes;
1141 pfad->ftCreationTime = FileData.ftCreationTime;
1142 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1143 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1144 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1145 pfad->nFileSizeLow = FileData.nFileSizeLow;
1146 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001147}
1148
Victor Stinnerd6f85422010-05-05 23:33:33 +00001149static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001150win32_stat(const char* path, struct win32_stat *result)
1151{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001152 WIN32_FILE_ATTRIBUTE_DATA info;
1153 int code;
1154 char *dot;
1155 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1156 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1157 /* Protocol violation: we explicitly clear errno, instead of
1158 setting it to a POSIX error. Callers should use GetLastError. */
1159 errno = 0;
1160 return -1;
1161 } else {
1162 /* Could not get attributes on open file. Fall back to
1163 reading the directory. */
1164 if (!attributes_from_dir(path, &info)) {
1165 /* Very strange. This should not fail now */
1166 errno = 0;
1167 return -1;
1168 }
1169 }
1170 }
1171 code = attribute_data_to_stat(&info, result);
1172 if (code != 0)
1173 return code;
1174 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1175 dot = strrchr(path, '.');
1176 if (dot) {
1177 if (stricmp(dot, ".bat") == 0 ||
1178 stricmp(dot, ".cmd") == 0 ||
1179 stricmp(dot, ".exe") == 0 ||
1180 stricmp(dot, ".com") == 0)
1181 result->st_mode |= 0111;
1182 }
1183 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001184}
1185
Victor Stinnerd6f85422010-05-05 23:33:33 +00001186static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001187win32_wstat(const wchar_t* path, struct win32_stat *result)
1188{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001189 int code;
1190 const wchar_t *dot;
1191 WIN32_FILE_ATTRIBUTE_DATA info;
1192 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1193 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1194 /* Protocol violation: we explicitly clear errno, instead of
1195 setting it to a POSIX error. Callers should use GetLastError. */
1196 errno = 0;
1197 return -1;
1198 } else {
1199 /* Could not get attributes on open file. Fall back to
1200 reading the directory. */
1201 if (!attributes_from_dir_w(path, &info)) {
1202 /* Very strange. This should not fail now */
1203 errno = 0;
1204 return -1;
1205 }
1206 }
1207 }
1208 code = attribute_data_to_stat(&info, result);
1209 if (code < 0)
1210 return code;
1211 /* Set IFEXEC if it is an .exe, .bat, ... */
1212 dot = wcsrchr(path, '.');
1213 if (dot) {
1214 if (_wcsicmp(dot, L".bat") == 0 ||
1215 _wcsicmp(dot, L".cmd") == 0 ||
1216 _wcsicmp(dot, L".exe") == 0 ||
1217 _wcsicmp(dot, L".com") == 0)
1218 result->st_mode |= 0111;
1219 }
1220 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001221}
1222
1223static int
1224win32_fstat(int file_number, struct win32_stat *result)
1225{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001226 BY_HANDLE_FILE_INFORMATION info;
1227 HANDLE h;
1228 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001229
Victor Stinnerd6f85422010-05-05 23:33:33 +00001230 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001231
Victor Stinnerd6f85422010-05-05 23:33:33 +00001232 /* Protocol violation: we explicitly clear errno, instead of
1233 setting it to a POSIX error. Callers should use GetLastError. */
1234 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001235
Victor Stinnerd6f85422010-05-05 23:33:33 +00001236 if (h == INVALID_HANDLE_VALUE) {
1237 /* This is really a C library error (invalid file handle).
1238 We set the Win32 error to the closes one matching. */
1239 SetLastError(ERROR_INVALID_HANDLE);
1240 return -1;
1241 }
1242 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001243
Victor Stinnerd6f85422010-05-05 23:33:33 +00001244 type = GetFileType(h);
1245 if (type == FILE_TYPE_UNKNOWN) {
1246 DWORD error = GetLastError();
1247 if (error != 0) {
1248 return -1;
1249 }
1250 /* else: valid but unknown file */
1251 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001252
Victor Stinnerd6f85422010-05-05 23:33:33 +00001253 if (type != FILE_TYPE_DISK) {
1254 if (type == FILE_TYPE_CHAR)
1255 result->st_mode = _S_IFCHR;
1256 else if (type == FILE_TYPE_PIPE)
1257 result->st_mode = _S_IFIFO;
1258 return 0;
1259 }
1260
1261 if (!GetFileInformationByHandle(h, &info)) {
1262 return -1;
1263 }
1264
1265 /* similar to stat() */
1266 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1267 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1268 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1269 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1270 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1271 /* specific to fstat() */
1272 result->st_nlink = info.nNumberOfLinks;
1273 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1274 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001275}
1276
1277#endif /* MS_WINDOWS */
1278
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001279PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001280"stat_result: Result from stat or lstat.\n\n\
1281This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001282 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001283or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1284\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001285Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1286or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001287\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001288See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001289
1290static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001291 {"st_mode", "protection bits"},
1292 {"st_ino", "inode"},
1293 {"st_dev", "device"},
1294 {"st_nlink", "number of hard links"},
1295 {"st_uid", "user ID of owner"},
1296 {"st_gid", "group ID of owner"},
1297 {"st_size", "total size, in bytes"},
1298 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1299 {NULL, "integer time of last access"},
1300 {NULL, "integer time of last modification"},
1301 {NULL, "integer time of last change"},
1302 {"st_atime", "time of last access"},
1303 {"st_mtime", "time of last modification"},
1304 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001305#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001306 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001307#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001308#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001309 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001310#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001311#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001312 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001313#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001314#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001315 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001316#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001317#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001318 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001319#endif
1320#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001321 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001322#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001323 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001324};
1325
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001326#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001327#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001328#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001329#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001330#endif
1331
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001332#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1334#else
1335#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1336#endif
1337
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001338#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1340#else
1341#define ST_RDEV_IDX ST_BLOCKS_IDX
1342#endif
1343
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001344#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1345#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1346#else
1347#define ST_FLAGS_IDX ST_RDEV_IDX
1348#endif
1349
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001350#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001351#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001352#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001353#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001354#endif
1355
1356#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1357#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1358#else
1359#define ST_BIRTHTIME_IDX ST_GEN_IDX
1360#endif
1361
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001362static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001363 "stat_result", /* name */
1364 stat_result__doc__, /* doc */
1365 stat_result_fields,
1366 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001367};
1368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001369PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001370"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1371This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001372 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001373or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001374\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001375See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001376
1377static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001378 {"f_bsize", },
1379 {"f_frsize", },
1380 {"f_blocks", },
1381 {"f_bfree", },
1382 {"f_bavail", },
1383 {"f_files", },
1384 {"f_ffree", },
1385 {"f_favail", },
1386 {"f_flag", },
1387 {"f_namemax",},
1388 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001389};
1390
1391static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001392 "statvfs_result", /* name */
1393 statvfs_result__doc__, /* doc */
1394 statvfs_result_fields,
1395 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001396};
1397
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001398static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001399static PyTypeObject StatResultType;
1400static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001401static newfunc structseq_new;
1402
1403static PyObject *
1404statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1405{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001406 PyStructSequence *result;
1407 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001408
Victor Stinnerd6f85422010-05-05 23:33:33 +00001409 result = (PyStructSequence*)structseq_new(type, args, kwds);
1410 if (!result)
1411 return NULL;
1412 /* If we have been initialized from a tuple,
1413 st_?time might be set to None. Initialize it
1414 from the int slots. */
1415 for (i = 7; i <= 9; i++) {
1416 if (result->ob_item[i+3] == Py_None) {
1417 Py_DECREF(Py_None);
1418 Py_INCREF(result->ob_item[i]);
1419 result->ob_item[i+3] = result->ob_item[i];
1420 }
1421 }
1422 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001423}
1424
1425
1426
1427/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001428static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001429
1430PyDoc_STRVAR(stat_float_times__doc__,
1431"stat_float_times([newval]) -> oldval\n\n\
1432Determine whether os.[lf]stat represents time stamps as float objects.\n\
1433If newval is True, future calls to stat() return floats, if it is False,\n\
1434future calls return ints. \n\
1435If newval is omitted, return the current setting.\n");
1436
1437static PyObject*
1438stat_float_times(PyObject* self, PyObject *args)
1439{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001440 int newval = -1;
1441 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1442 return NULL;
1443 if (newval == -1)
1444 /* Return old value */
1445 return PyBool_FromLong(_stat_float_times);
1446 _stat_float_times = newval;
1447 Py_INCREF(Py_None);
1448 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001449}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001450
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001451static void
1452fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1453{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001454 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001455#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001456 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001457#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001458 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001459#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001460 if (!ival)
1461 return;
1462 if (_stat_float_times) {
1463 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1464 } else {
1465 fval = ival;
1466 Py_INCREF(fval);
1467 }
1468 PyStructSequence_SET_ITEM(v, index, ival);
1469 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001470}
1471
Tim Peters5aa91602002-01-30 05:46:57 +00001472/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001473 (used by posix_stat() and posix_fstat()) */
1474static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001475_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001476{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001477 unsigned long ansec, mnsec, cnsec;
1478 PyObject *v = PyStructSequence_New(&StatResultType);
1479 if (v == NULL)
1480 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001481
Victor Stinnerd6f85422010-05-05 23:33:33 +00001482 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001483#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001484 PyStructSequence_SET_ITEM(v, 1,
1485 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001486#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001487 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001488#endif
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001489#ifdef MS_WINDOWS
1490 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001491#else
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001492 PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001493#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001494 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02001495#if defined(MS_WINDOWS)
1496 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
1497 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
1498#else
1499 PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
1500 PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
1501#endif
Fred Drake699f3522000-06-29 21:12:41 +00001502#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001503 PyStructSequence_SET_ITEM(v, 6,
1504 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001505#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001506 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001507#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001508
Martin v. Löwis14694662006-02-03 12:54:16 +00001509#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001510 ansec = st->st_atim.tv_nsec;
1511 mnsec = st->st_mtim.tv_nsec;
1512 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001513#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001514 ansec = st->st_atimespec.tv_nsec;
1515 mnsec = st->st_mtimespec.tv_nsec;
1516 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001517#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001518 ansec = st->st_atime_nsec;
1519 mnsec = st->st_mtime_nsec;
1520 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001521#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001522 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001523#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001524 fill_time(v, 7, st->st_atime, ansec);
1525 fill_time(v, 8, st->st_mtime, mnsec);
1526 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001527
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001528#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001529 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1530 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001531#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001532#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001533 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1534 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001535#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001536#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001537 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1538 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001539#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001540#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001541 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1542 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001543#endif
1544#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001545 {
1546 PyObject *val;
1547 unsigned long bsec,bnsec;
1548 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001549#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001550 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001551#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001552 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001553#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001554 if (_stat_float_times) {
1555 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1556 } else {
1557 val = PyInt_FromLong((long)bsec);
1558 }
1559 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1560 val);
1561 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001562#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001563#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001564 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1565 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001566#endif
Fred Drake699f3522000-06-29 21:12:41 +00001567
Victor Stinnerd6f85422010-05-05 23:33:33 +00001568 if (PyErr_Occurred()) {
1569 Py_DECREF(v);
1570 return NULL;
1571 }
Fred Drake699f3522000-06-29 21:12:41 +00001572
Victor Stinnerd6f85422010-05-05 23:33:33 +00001573 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001574}
1575
Martin v. Löwisd8948722004-06-02 09:57:56 +00001576#ifdef MS_WINDOWS
1577
1578/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1579 where / can be used in place of \ and the trailing slash is optional.
1580 Both SERVER and SHARE must have at least one character.
1581*/
1582
1583#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1584#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001585#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001586#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001587#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001588
Tim Peters4ad82172004-08-30 17:02:04 +00001589static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001590IsUNCRootA(char *path, int pathlen)
1591{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001592 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001593
Victor Stinnerd6f85422010-05-05 23:33:33 +00001594 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001595
Victor Stinnerd6f85422010-05-05 23:33:33 +00001596 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1597 /* minimum UNCRoot is \\x\y */
1598 return FALSE;
1599 for (i = 2; i < pathlen ; i++)
1600 if (ISSLASH(path[i])) break;
1601 if (i == 2 || i == pathlen)
1602 /* do not allow \\\SHARE or \\SERVER */
1603 return FALSE;
1604 share = i+1;
1605 for (i = share; i < pathlen; i++)
1606 if (ISSLASH(path[i])) break;
1607 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001608
Victor Stinnerd6f85422010-05-05 23:33:33 +00001609 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001610}
1611
Tim Peters4ad82172004-08-30 17:02:04 +00001612static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001613IsUNCRootW(Py_UNICODE *path, int pathlen)
1614{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001615 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001616
Victor Stinnerd6f85422010-05-05 23:33:33 +00001617 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001618
Victor Stinnerd6f85422010-05-05 23:33:33 +00001619 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1620 /* minimum UNCRoot is \\x\y */
1621 return FALSE;
1622 for (i = 2; i < pathlen ; i++)
1623 if (ISSLASH(path[i])) break;
1624 if (i == 2 || i == pathlen)
1625 /* do not allow \\\SHARE or \\SERVER */
1626 return FALSE;
1627 share = i+1;
1628 for (i = share; i < pathlen; i++)
1629 if (ISSLASH(path[i])) break;
1630 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001631
Victor Stinnerd6f85422010-05-05 23:33:33 +00001632 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001633}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001634#endif /* MS_WINDOWS */
1635
Barry Warsaw53699e91996-12-10 23:23:01 +00001636static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001637posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001638 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001639#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001640 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001641#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001643#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001644 char *wformat,
1645 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001646{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001647 STRUCT_STAT st;
1648 char *path = NULL; /* pass this to stat; do not free() it */
1649 char *pathfree = NULL; /* this memory must be free'd */
1650 int res;
1651 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001652
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001653#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001654 Py_UNICODE *wpath;
1655 if (PyArg_ParseTuple(args, wformat, &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001656 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001657 res = wstatfunc(wpath, &st);
1658 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001659
Victor Stinnerd6f85422010-05-05 23:33:33 +00001660 if (res != 0)
1661 return win32_error_unicode("stat", wpath);
1662 return _pystat_fromstructstat(&st);
1663 }
1664 /* Drop the argument parsing error as narrow strings
1665 are also valid. */
1666 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001667#endif
1668
Victor Stinnerd6f85422010-05-05 23:33:33 +00001669 if (!PyArg_ParseTuple(args, format,
1670 Py_FileSystemDefaultEncoding, &path))
1671 return NULL;
1672 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001673
Victor Stinnerd6f85422010-05-05 23:33:33 +00001674 Py_BEGIN_ALLOW_THREADS
1675 res = (*statfunc)(path, &st);
1676 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001677
Victor Stinnerd6f85422010-05-05 23:33:33 +00001678 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001679#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001680 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001681#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001682 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001683#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001684 }
1685 else
1686 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001687
Victor Stinnerd6f85422010-05-05 23:33:33 +00001688 PyMem_Free(pathfree);
1689 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001690}
1691
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001692/* POSIX methods */
1693
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001694PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001695"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001696Use the real uid/gid to test for access to a path. Note that most\n\
1697operations will use the effective uid/gid, therefore this routine can\n\
1698be used in a suid/sgid environment to test if the invoking user has the\n\
1699specified access to the path. The mode argument can be F_OK to test\n\
1700existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001701
1702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001703posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001704{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001705 char *path;
1706 int mode;
1707
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001708#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001709 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001710 Py_UNICODE *wpath;
1711 if (PyArg_ParseTuple(args, "ui:access", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001712 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001713 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001714 Py_END_ALLOW_THREADS
1715 goto finish;
1716 }
1717 /* Drop the argument parsing error as narrow strings
1718 are also valid. */
1719 PyErr_Clear();
1720 if (!PyArg_ParseTuple(args, "eti:access",
1721 Py_FileSystemDefaultEncoding, &path, &mode))
1722 return NULL;
1723 Py_BEGIN_ALLOW_THREADS
1724 attr = GetFileAttributesA(path);
1725 Py_END_ALLOW_THREADS
1726 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001727finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001728 if (attr == 0xFFFFFFFF)
1729 /* File does not exist, or cannot read attributes */
1730 return PyBool_FromLong(0);
1731 /* Access is possible if either write access wasn't requested, or
1732 the file isn't read-only, or if it's a directory, as there are
1733 no read-only directories on Windows. */
1734 return PyBool_FromLong(!(mode & 2)
1735 || !(attr & FILE_ATTRIBUTE_READONLY)
1736 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001737#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001738 int res;
1739 if (!PyArg_ParseTuple(args, "eti:access",
1740 Py_FileSystemDefaultEncoding, &path, &mode))
1741 return NULL;
1742 Py_BEGIN_ALLOW_THREADS
1743 res = access(path, mode);
1744 Py_END_ALLOW_THREADS
1745 PyMem_Free(path);
1746 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001747#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001748}
1749
Guido van Rossumd371ff11999-01-25 16:12:23 +00001750#ifndef F_OK
1751#define F_OK 0
1752#endif
1753#ifndef R_OK
1754#define R_OK 4
1755#endif
1756#ifndef W_OK
1757#define W_OK 2
1758#endif
1759#ifndef X_OK
1760#define X_OK 1
1761#endif
1762
1763#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001764PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001765"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001766Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001767
1768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001769posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001770{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001771 int id;
1772 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001773
Victor Stinnerd6f85422010-05-05 23:33:33 +00001774 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1775 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001776
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001777#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001778 /* file descriptor 0 only, the default input device (stdin) */
1779 if (id == 0) {
1780 ret = ttyname();
1781 }
1782 else {
1783 ret = NULL;
1784 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001785#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001786 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001787#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001788 if (ret == NULL)
1789 return posix_error();
1790 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001791}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001792#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001793
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001794#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001795PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001796"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001798
1799static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001800posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001801{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001802 char *ret;
1803 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804
Greg Wardb48bc172000-03-01 21:51:56 +00001805#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001806 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001807#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001808 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001809#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001810 if (ret == NULL)
1811 return posix_error();
1812 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001813}
1814#endif
1815
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001816PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001817"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001818Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001819
Barry Warsaw53699e91996-12-10 23:23:01 +00001820static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001821posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001822{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001823#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001824 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001825#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001826 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001827#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001828 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001829#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001830 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001831#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001832}
1833
Fred Drake4d1e64b2002-04-15 19:40:07 +00001834#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001837Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001839
1840static PyObject *
1841posix_fchdir(PyObject *self, PyObject *fdobj)
1842{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001843 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001844}
1845#endif /* HAVE_FCHDIR */
1846
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001847
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Barry Warsaw53699e91996-12-10 23:23:01 +00001852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001853posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001854{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001855 char *path = NULL;
1856 int i;
1857 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001858#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001859 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001860 Py_UNICODE *wpath;
1861 if (PyArg_ParseTuple(args, "ui|:chmod", &wpath, &i)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001862 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001863 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001864 if (attr != 0xFFFFFFFF) {
1865 if (i & _S_IWRITE)
1866 attr &= ~FILE_ATTRIBUTE_READONLY;
1867 else
1868 attr |= FILE_ATTRIBUTE_READONLY;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001869 res = SetFileAttributesW(wpath, attr);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001870 }
1871 else
1872 res = 0;
1873 Py_END_ALLOW_THREADS
1874 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001875 return win32_error_unicode("chmod", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001876 Py_INCREF(Py_None);
1877 return Py_None;
1878 }
1879 /* Drop the argument parsing error as narrow strings
1880 are also valid. */
1881 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001882
Victor Stinnerd6f85422010-05-05 23:33:33 +00001883 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1884 &path, &i))
1885 return NULL;
1886 Py_BEGIN_ALLOW_THREADS
1887 attr = GetFileAttributesA(path);
1888 if (attr != 0xFFFFFFFF) {
1889 if (i & _S_IWRITE)
1890 attr &= ~FILE_ATTRIBUTE_READONLY;
1891 else
1892 attr |= FILE_ATTRIBUTE_READONLY;
1893 res = SetFileAttributesA(path, attr);
1894 }
1895 else
1896 res = 0;
1897 Py_END_ALLOW_THREADS
1898 if (!res) {
1899 win32_error("chmod", path);
1900 PyMem_Free(path);
1901 return NULL;
1902 }
1903 PyMem_Free(path);
1904 Py_INCREF(Py_None);
1905 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001906#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001907 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1908 &path, &i))
1909 return NULL;
1910 Py_BEGIN_ALLOW_THREADS
1911 res = chmod(path, i);
1912 Py_END_ALLOW_THREADS
1913 if (res < 0)
1914 return posix_error_with_allocated_filename(path);
1915 PyMem_Free(path);
1916 Py_INCREF(Py_None);
1917 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001918#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001919}
1920
Christian Heimes36281872007-11-30 21:11:28 +00001921#ifdef HAVE_FCHMOD
1922PyDoc_STRVAR(posix_fchmod__doc__,
1923"fchmod(fd, mode)\n\n\
1924Change the access permissions of the file given by file\n\
1925descriptor fd.");
1926
1927static PyObject *
1928posix_fchmod(PyObject *self, PyObject *args)
1929{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001930 int fd, mode, res;
1931 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1932 return NULL;
1933 Py_BEGIN_ALLOW_THREADS
1934 res = fchmod(fd, mode);
1935 Py_END_ALLOW_THREADS
1936 if (res < 0)
1937 return posix_error();
1938 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001939}
1940#endif /* HAVE_FCHMOD */
1941
1942#ifdef HAVE_LCHMOD
1943PyDoc_STRVAR(posix_lchmod__doc__,
1944"lchmod(path, mode)\n\n\
1945Change the access permissions of a file. If path is a symlink, this\n\
1946affects the link itself rather than the target.");
1947
1948static PyObject *
1949posix_lchmod(PyObject *self, PyObject *args)
1950{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001951 char *path = NULL;
1952 int i;
1953 int res;
1954 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1955 &path, &i))
1956 return NULL;
1957 Py_BEGIN_ALLOW_THREADS
1958 res = lchmod(path, i);
1959 Py_END_ALLOW_THREADS
1960 if (res < 0)
1961 return posix_error_with_allocated_filename(path);
1962 PyMem_Free(path);
1963 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001964}
1965#endif /* HAVE_LCHMOD */
1966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Martin v. Löwis382abef2007-02-19 10:55:19 +00001968#ifdef HAVE_CHFLAGS
1969PyDoc_STRVAR(posix_chflags__doc__,
1970"chflags(path, flags)\n\n\
1971Set file flags.");
1972
1973static PyObject *
1974posix_chflags(PyObject *self, PyObject *args)
1975{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001976 char *path;
1977 unsigned long flags;
1978 int res;
1979 if (!PyArg_ParseTuple(args, "etk:chflags",
1980 Py_FileSystemDefaultEncoding, &path, &flags))
1981 return NULL;
1982 Py_BEGIN_ALLOW_THREADS
1983 res = chflags(path, flags);
1984 Py_END_ALLOW_THREADS
1985 if (res < 0)
1986 return posix_error_with_allocated_filename(path);
1987 PyMem_Free(path);
1988 Py_INCREF(Py_None);
1989 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001990}
1991#endif /* HAVE_CHFLAGS */
1992
1993#ifdef HAVE_LCHFLAGS
1994PyDoc_STRVAR(posix_lchflags__doc__,
1995"lchflags(path, flags)\n\n\
1996Set file flags.\n\
1997This function will not follow symbolic links.");
1998
1999static PyObject *
2000posix_lchflags(PyObject *self, PyObject *args)
2001{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002002 char *path;
2003 unsigned long flags;
2004 int res;
2005 if (!PyArg_ParseTuple(args, "etk:lchflags",
2006 Py_FileSystemDefaultEncoding, &path, &flags))
2007 return NULL;
2008 Py_BEGIN_ALLOW_THREADS
2009 res = lchflags(path, flags);
2010 Py_END_ALLOW_THREADS
2011 if (res < 0)
2012 return posix_error_with_allocated_filename(path);
2013 PyMem_Free(path);
2014 Py_INCREF(Py_None);
2015 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00002016}
2017#endif /* HAVE_LCHFLAGS */
2018
Martin v. Löwis244edc82001-10-04 22:44:26 +00002019#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002021"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002023
2024static PyObject *
2025posix_chroot(PyObject *self, PyObject *args)
2026{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002027 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002028}
2029#endif
2030
Guido van Rossum21142a01999-01-08 21:05:37 +00002031#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002033"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002035
2036static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002037posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002038{
Stefan Krah93f7a322010-11-26 17:35:50 +00002039 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002040}
2041#endif /* HAVE_FSYNC */
2042
2043#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002044
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002045#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002046extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2047#endif
2048
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002050"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002051force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002052 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002053
2054static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002055posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002056{
Stefan Krah93f7a322010-11-26 17:35:50 +00002057 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002058}
2059#endif /* HAVE_FDATASYNC */
2060
2061
Fredrik Lundh10723342000-07-10 16:38:09 +00002062#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002064"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Barry Warsaw53699e91996-12-10 23:23:01 +00002067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002068posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002069{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002070 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002071 uid_t uid;
2072 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002073 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002074 if (!PyArg_ParseTuple(args, "etO&O&:chown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002075 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002076 _Py_Uid_Converter, &uid,
2077 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002078 return NULL;
2079 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002080 res = chown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002081 Py_END_ALLOW_THREADS
2082 if (res < 0)
2083 return posix_error_with_allocated_filename(path);
2084 PyMem_Free(path);
2085 Py_INCREF(Py_None);
2086 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002087}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002088#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002089
Christian Heimes36281872007-11-30 21:11:28 +00002090#ifdef HAVE_FCHOWN
2091PyDoc_STRVAR(posix_fchown__doc__,
2092"fchown(fd, uid, gid)\n\n\
2093Change the owner and group id of the file given by file descriptor\n\
2094fd to the numeric uid and gid.");
2095
2096static PyObject *
2097posix_fchown(PyObject *self, PyObject *args)
2098{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002099 int fd;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002100 uid_t uid;
2101 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002102 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002103 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
2104 _Py_Uid_Converter, &uid,
2105 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002106 return NULL;
2107 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002108 res = fchown(fd, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002109 Py_END_ALLOW_THREADS
2110 if (res < 0)
2111 return posix_error();
2112 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00002113}
2114#endif /* HAVE_FCHOWN */
2115
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002116#ifdef HAVE_LCHOWN
2117PyDoc_STRVAR(posix_lchown__doc__,
2118"lchown(path, uid, gid)\n\n\
2119Change the owner and group id of path to the numeric uid and gid.\n\
2120This function will not follow symbolic links.");
2121
2122static PyObject *
2123posix_lchown(PyObject *self, PyObject *args)
2124{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002125 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002126 uid_t uid;
2127 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002128 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002129 if (!PyArg_ParseTuple(args, "etO&O&:lchown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002130 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002131 _Py_Uid_Converter, &uid,
2132 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002133 return NULL;
2134 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002135 res = lchown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002136 Py_END_ALLOW_THREADS
2137 if (res < 0)
2138 return posix_error_with_allocated_filename(path);
2139 PyMem_Free(path);
2140 Py_INCREF(Py_None);
2141 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002142}
2143#endif /* HAVE_LCHOWN */
2144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145
Guido van Rossum36bc6801995-06-14 22:54:23 +00002146#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002147PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002148"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002149Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002150
Trent Nelsonda4277a2012-08-29 09:20:41 -04002151#if (defined(__sun) && defined(__SVR4)) || \
2152 defined(__OpenBSD__) || \
2153 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00002154/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
2155static PyObject *
2156posix_getcwd(PyObject *self, PyObject *noargs)
2157{
2158 char buf[PATH_MAX+2];
2159 char *res;
2160
2161 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00002162 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00002163 Py_END_ALLOW_THREADS
2164
2165 if (res == NULL)
2166 return posix_error();
2167
2168 return PyString_FromString(buf);
2169}
2170#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002171static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002172posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002173{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002174 int bufsize_incr = 1024;
2175 int bufsize = 0;
2176 char *tmpbuf = NULL;
2177 char *res = NULL;
2178 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002179
Victor Stinnerd6f85422010-05-05 23:33:33 +00002180 Py_BEGIN_ALLOW_THREADS
2181 do {
2182 bufsize = bufsize + bufsize_incr;
2183 tmpbuf = malloc(bufsize);
2184 if (tmpbuf == NULL) {
2185 break;
2186 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002187#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002188 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002189#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002190 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002191#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002192
Victor Stinnerd6f85422010-05-05 23:33:33 +00002193 if (res == NULL) {
2194 free(tmpbuf);
2195 }
2196 } while ((res == NULL) && (errno == ERANGE));
2197 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002198
Victor Stinnerd6f85422010-05-05 23:33:33 +00002199 if (res == NULL)
2200 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002201
Victor Stinnerd6f85422010-05-05 23:33:33 +00002202 dynamic_return = PyString_FromString(tmpbuf);
2203 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002204
Victor Stinnerd6f85422010-05-05 23:33:33 +00002205 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002206}
Stefan Krah182ae642010-07-13 19:17:08 +00002207#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002208
Walter Dörwald3b918c32002-11-21 20:18:46 +00002209#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002210PyDoc_STRVAR(posix_getcwdu__doc__,
2211"getcwdu() -> path\n\n\
2212Return a unicode string representing the current working directory.");
2213
2214static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002215posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002216{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002217 char buf[1026];
2218 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002219
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002220#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002221 DWORD len;
2222 wchar_t wbuf[1026];
2223 wchar_t *wbuf2 = wbuf;
2224 PyObject *resobj;
2225 Py_BEGIN_ALLOW_THREADS
2226 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2227 /* If the buffer is large enough, len does not include the
2228 terminating \0. If the buffer is too small, len includes
2229 the space needed for the terminator. */
2230 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2231 wbuf2 = malloc(len * sizeof(wchar_t));
2232 if (wbuf2)
2233 len = GetCurrentDirectoryW(len, wbuf2);
2234 }
2235 Py_END_ALLOW_THREADS
2236 if (!wbuf2) {
2237 PyErr_NoMemory();
2238 return NULL;
2239 }
2240 if (!len) {
2241 if (wbuf2 != wbuf) free(wbuf2);
2242 return win32_error("getcwdu", NULL);
2243 }
2244 resobj = PyUnicode_FromWideChar(wbuf2, len);
2245 if (wbuf2 != wbuf) free(wbuf2);
2246 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002247#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002248
Victor Stinnerd6f85422010-05-05 23:33:33 +00002249 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002250#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002251 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002252#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002253 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002254#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002255 Py_END_ALLOW_THREADS
2256 if (res == NULL)
2257 return posix_error();
2258 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002259}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002260#endif /* Py_USING_UNICODE */
2261#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002263
Guido van Rossumb6775db1994-08-01 11:34:53 +00002264#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002265PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002266"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002267Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002268
Barry Warsaw53699e91996-12-10 23:23:01 +00002269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002270posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002271{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002272 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002273}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002274#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002278"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002279Return a list containing the names of the entries in the directory.\n\
2280\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002281 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002282\n\
2283The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002284entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002285
Barry Warsaw53699e91996-12-10 23:23:01 +00002286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002287posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002289 /* XXX Should redo this putting the (now four) versions of opendir
2290 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002291#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002292
Victor Stinnerd6f85422010-05-05 23:33:33 +00002293 PyObject *d, *v;
2294 HANDLE hFindFile;
2295 BOOL result;
2296 WIN32_FIND_DATA FileData;
2297 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2298 char *bufptr = namebuf;
2299 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002300
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002301 Py_UNICODE *wpath;
2302 if (PyArg_ParseTuple(args, "u:listdir", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002303 WIN32_FIND_DATAW wFileData;
2304 Py_UNICODE *wnamebuf;
2305 /* Overallocate for \\*.*\0 */
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002306 len = wcslen(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002307 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2308 if (!wnamebuf) {
2309 PyErr_NoMemory();
2310 return NULL;
2311 }
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002312 wcscpy(wnamebuf, wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002313 if (len > 0) {
2314 Py_UNICODE wch = wnamebuf[len-1];
2315 if (wch != L'/' && wch != L'\\' && wch != L':')
2316 wnamebuf[len++] = L'\\';
2317 wcscpy(wnamebuf + len, L"*.*");
2318 }
2319 if ((d = PyList_New(0)) == NULL) {
2320 free(wnamebuf);
2321 return NULL;
2322 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002323 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002324 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002325 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002326 if (hFindFile == INVALID_HANDLE_VALUE) {
2327 int error = GetLastError();
2328 if (error == ERROR_FILE_NOT_FOUND) {
2329 free(wnamebuf);
2330 return d;
2331 }
2332 Py_DECREF(d);
2333 win32_error_unicode("FindFirstFileW", wnamebuf);
2334 free(wnamebuf);
2335 return NULL;
2336 }
2337 do {
2338 /* Skip over . and .. */
2339 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2340 wcscmp(wFileData.cFileName, L"..") != 0) {
2341 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2342 if (v == NULL) {
2343 Py_DECREF(d);
2344 d = NULL;
2345 break;
2346 }
2347 if (PyList_Append(d, v) != 0) {
2348 Py_DECREF(v);
2349 Py_DECREF(d);
2350 d = NULL;
2351 break;
2352 }
2353 Py_DECREF(v);
2354 }
2355 Py_BEGIN_ALLOW_THREADS
2356 result = FindNextFileW(hFindFile, &wFileData);
2357 Py_END_ALLOW_THREADS
2358 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2359 it got to the end of the directory. */
2360 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2361 Py_DECREF(d);
2362 win32_error_unicode("FindNextFileW", wnamebuf);
2363 FindClose(hFindFile);
2364 free(wnamebuf);
2365 return NULL;
2366 }
2367 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002368
Victor Stinnerd6f85422010-05-05 23:33:33 +00002369 if (FindClose(hFindFile) == FALSE) {
2370 Py_DECREF(d);
2371 win32_error_unicode("FindClose", wnamebuf);
2372 free(wnamebuf);
2373 return NULL;
2374 }
2375 free(wnamebuf);
2376 return d;
2377 }
2378 /* Drop the argument parsing error as narrow strings
2379 are also valid. */
2380 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002381
Victor Stinnerd6f85422010-05-05 23:33:33 +00002382 if (!PyArg_ParseTuple(args, "et#:listdir",
2383 Py_FileSystemDefaultEncoding, &bufptr, &len))
2384 return NULL;
2385 if (len > 0) {
2386 char ch = namebuf[len-1];
2387 if (ch != SEP && ch != ALTSEP && ch != ':')
Anthony Sottile27f32e92018-01-15 13:39:04 -08002388 namebuf[len++] = SEP;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002389 strcpy(namebuf + len, "*.*");
2390 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002391
Victor Stinnerd6f85422010-05-05 23:33:33 +00002392 if ((d = PyList_New(0)) == NULL)
2393 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002394
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002395 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002396 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002397 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002398 if (hFindFile == INVALID_HANDLE_VALUE) {
2399 int error = GetLastError();
2400 if (error == ERROR_FILE_NOT_FOUND)
2401 return d;
2402 Py_DECREF(d);
2403 return win32_error("FindFirstFile", namebuf);
2404 }
2405 do {
2406 /* Skip over . and .. */
2407 if (strcmp(FileData.cFileName, ".") != 0 &&
2408 strcmp(FileData.cFileName, "..") != 0) {
2409 v = PyString_FromString(FileData.cFileName);
2410 if (v == NULL) {
2411 Py_DECREF(d);
2412 d = NULL;
2413 break;
2414 }
2415 if (PyList_Append(d, v) != 0) {
2416 Py_DECREF(v);
2417 Py_DECREF(d);
2418 d = NULL;
2419 break;
2420 }
2421 Py_DECREF(v);
2422 }
2423 Py_BEGIN_ALLOW_THREADS
2424 result = FindNextFile(hFindFile, &FileData);
2425 Py_END_ALLOW_THREADS
2426 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2427 it got to the end of the directory. */
2428 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2429 Py_DECREF(d);
2430 win32_error("FindNextFile", namebuf);
2431 FindClose(hFindFile);
2432 return NULL;
2433 }
2434 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002435
Victor Stinnerd6f85422010-05-05 23:33:33 +00002436 if (FindClose(hFindFile) == FALSE) {
2437 Py_DECREF(d);
2438 return win32_error("FindClose", namebuf);
2439 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002440
Victor Stinnerd6f85422010-05-05 23:33:33 +00002441 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002442
Tim Peters0bb44a42000-09-15 07:44:49 +00002443#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002444
2445#ifndef MAX_PATH
2446#define MAX_PATH CCHMAXPATH
2447#endif
2448 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002449 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002450 PyObject *d, *v;
2451 char namebuf[MAX_PATH+5];
2452 HDIR hdir = 1;
2453 ULONG srchcnt = 1;
2454 FILEFINDBUF3 ep;
2455 APIRET rc;
2456
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002457 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002458 return NULL;
2459 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002460 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002461 return NULL;
2462 }
2463 strcpy(namebuf, name);
2464 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002465 if (*pt == ALTSEP)
2466 *pt = SEP;
2467 if (namebuf[len-1] != SEP)
2468 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002469 strcpy(namebuf + len, "*.*");
2470
Victor Stinnerd6f85422010-05-05 23:33:33 +00002471 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002472 return NULL;
2473
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002474 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2475 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002476 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002477 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2478 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2479 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002480
2481 if (rc != NO_ERROR) {
2482 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002483 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002484 }
2485
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002486 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002487 do {
2488 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002489 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002490 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002491
2492 strcpy(namebuf, ep.achName);
2493
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002494 /* Leave Case of Name Alone -- In Native Form */
2495 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002496
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002497 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002498 if (v == NULL) {
2499 Py_DECREF(d);
2500 d = NULL;
2501 break;
2502 }
2503 if (PyList_Append(d, v) != 0) {
2504 Py_DECREF(v);
2505 Py_DECREF(d);
2506 d = NULL;
2507 break;
2508 }
2509 Py_DECREF(v);
2510 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2511 }
2512
2513 return d;
2514#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002515
Victor Stinnerd6f85422010-05-05 23:33:33 +00002516 char *name = NULL;
2517 PyObject *d, *v;
2518 DIR *dirp;
2519 struct dirent *ep;
2520 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002521
Victor Stinnerd6f85422010-05-05 23:33:33 +00002522 errno = 0;
2523 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2524 arg_is_unicode = 0;
2525 PyErr_Clear();
2526 }
2527 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2528 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002529 Py_BEGIN_ALLOW_THREADS
2530 dirp = opendir(name);
2531 Py_END_ALLOW_THREADS
2532 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002533 return posix_error_with_allocated_filename(name);
2534 }
2535 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002536 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002537 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002538 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002539 PyMem_Free(name);
2540 return NULL;
2541 }
2542 for (;;) {
2543 errno = 0;
2544 Py_BEGIN_ALLOW_THREADS
2545 ep = readdir(dirp);
2546 Py_END_ALLOW_THREADS
2547 if (ep == NULL) {
2548 if (errno == 0) {
2549 break;
2550 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002551 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002552 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002553 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002554 Py_DECREF(d);
2555 return posix_error_with_allocated_filename(name);
2556 }
2557 }
2558 if (ep->d_name[0] == '.' &&
2559 (NAMLEN(ep) == 1 ||
2560 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2561 continue;
2562 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2563 if (v == NULL) {
2564 Py_DECREF(d);
2565 d = NULL;
2566 break;
2567 }
Just van Rossum46c97842003-02-25 21:42:15 +00002568#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002569 if (arg_is_unicode) {
2570 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002571
Victor Stinnerd6f85422010-05-05 23:33:33 +00002572 w = PyUnicode_FromEncodedObject(v,
2573 Py_FileSystemDefaultEncoding,
2574 "strict");
2575 if (w != NULL) {
2576 Py_DECREF(v);
2577 v = w;
2578 }
2579 else {
2580 /* fall back to the original byte string, as
2581 discussed in patch #683592 */
2582 PyErr_Clear();
2583 }
2584 }
Just van Rossum46c97842003-02-25 21:42:15 +00002585#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002586 if (PyList_Append(d, v) != 0) {
2587 Py_DECREF(v);
2588 Py_DECREF(d);
2589 d = NULL;
2590 break;
2591 }
2592 Py_DECREF(v);
2593 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002594 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002595 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002596 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002597 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002598
Victor Stinnerd6f85422010-05-05 23:33:33 +00002599 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002600
Tim Peters0bb44a42000-09-15 07:44:49 +00002601#endif /* which OS */
2602} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002603
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002604#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002605/* A helper function for abspath on win32 */
2606static PyObject *
2607posix__getfullpathname(PyObject *self, PyObject *args)
2608{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002609 /* assume encoded strings won't more than double no of chars */
2610 char inbuf[MAX_PATH*2];
2611 char *inbufp = inbuf;
2612 Py_ssize_t insize = sizeof(inbuf);
2613 char outbuf[MAX_PATH*2];
2614 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002615
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002616 Py_UNICODE *wpath;
2617 if (PyArg_ParseTuple(args, "u|:_getfullpathname", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002618 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2619 Py_UNICODE *wtemp;
2620 DWORD result;
2621 PyObject *v;
2622 result = GetFullPathNameW(wpath,
2623 sizeof(woutbuf)/sizeof(woutbuf[0]),
2624 woutbuf, &wtemp);
2625 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2626 woutbufp = malloc(result * sizeof(Py_UNICODE));
2627 if (!woutbufp)
2628 return PyErr_NoMemory();
2629 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2630 }
2631 if (result)
2632 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2633 else
2634 v = win32_error_unicode("GetFullPathNameW", wpath);
2635 if (woutbufp != woutbuf)
2636 free(woutbufp);
2637 return v;
2638 }
2639 /* Drop the argument parsing error as narrow strings
2640 are also valid. */
2641 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002642
Victor Stinnerd6f85422010-05-05 23:33:33 +00002643 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2644 Py_FileSystemDefaultEncoding, &inbufp,
2645 &insize))
2646 return NULL;
2647 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2648 outbuf, &temp))
2649 return win32_error("GetFullPathName", inbuf);
2650 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2651 return PyUnicode_Decode(outbuf, strlen(outbuf),
2652 Py_FileSystemDefaultEncoding, NULL);
2653 }
2654 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002655} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002656#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002657
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002659"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002660Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002661
Barry Warsaw53699e91996-12-10 23:23:01 +00002662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002663posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002664{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002665 int res;
2666 char *path = NULL;
2667 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002668
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002669#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002670 Py_UNICODE *wpath;
2671 if (PyArg_ParseTuple(args, "u|i:mkdir", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002672 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002673 res = CreateDirectoryW(wpath, NULL);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002674 Py_END_ALLOW_THREADS
2675 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002676 return win32_error_unicode("mkdir", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002677 Py_INCREF(Py_None);
2678 return Py_None;
2679 }
2680 /* Drop the argument parsing error as narrow strings
2681 are also valid. */
2682 PyErr_Clear();
2683 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2684 Py_FileSystemDefaultEncoding, &path, &mode))
2685 return NULL;
2686 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002687 res = CreateDirectoryA(path, NULL);
2688 Py_END_ALLOW_THREADS
2689 if (!res) {
2690 win32_error("mkdir", path);
2691 PyMem_Free(path);
2692 return NULL;
2693 }
2694 PyMem_Free(path);
2695 Py_INCREF(Py_None);
2696 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002697#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002698
Victor Stinnerd6f85422010-05-05 23:33:33 +00002699 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2700 Py_FileSystemDefaultEncoding, &path, &mode))
2701 return NULL;
2702 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002703#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002704 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002705#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002706 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002707#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002708 Py_END_ALLOW_THREADS
2709 if (res < 0)
2710 return posix_error_with_allocated_filename(path);
2711 PyMem_Free(path);
2712 Py_INCREF(Py_None);
2713 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002714#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002715}
2716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002717
Neal Norwitz1818ed72006-03-26 00:29:48 +00002718/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2719#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002720#include <sys/resource.h>
2721#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002722
Neal Norwitz1818ed72006-03-26 00:29:48 +00002723
2724#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002725PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002726"nice(inc) -> new_priority\n\n\
2727Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002728
Barry Warsaw53699e91996-12-10 23:23:01 +00002729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002730posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002731{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002732 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002733
Victor Stinnerd6f85422010-05-05 23:33:33 +00002734 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2735 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002736
Victor Stinnerd6f85422010-05-05 23:33:33 +00002737 /* There are two flavours of 'nice': one that returns the new
2738 priority (as required by almost all standards out there) and the
2739 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2740 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002741
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 If we are of the nice family that returns the new priority, we
2743 need to clear errno before the call, and check if errno is filled
2744 before calling posix_error() on a returnvalue of -1, because the
2745 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002746
Victor Stinnerd6f85422010-05-05 23:33:33 +00002747 errno = 0;
2748 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002749#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002750 if (value == 0)
2751 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002752#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002753 if (value == -1 && errno != 0)
2754 /* either nice() or getpriority() returned an error */
2755 return posix_error();
2756 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002757}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002758#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002760PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002761"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002762Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002763
Barry Warsaw53699e91996-12-10 23:23:01 +00002764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002765posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002766{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002767#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002768 PyObject *o1, *o2;
2769 char *p1, *p2;
2770 BOOL result;
2771 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2772 goto error;
2773 if (!convert_to_unicode(&o1))
2774 goto error;
2775 if (!convert_to_unicode(&o2)) {
2776 Py_DECREF(o1);
2777 goto error;
2778 }
2779 Py_BEGIN_ALLOW_THREADS
2780 result = MoveFileW(PyUnicode_AsUnicode(o1),
2781 PyUnicode_AsUnicode(o2));
2782 Py_END_ALLOW_THREADS
2783 Py_DECREF(o1);
2784 Py_DECREF(o2);
2785 if (!result)
2786 return win32_error("rename", NULL);
2787 Py_INCREF(Py_None);
2788 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002789error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002790 PyErr_Clear();
2791 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2792 return NULL;
2793 Py_BEGIN_ALLOW_THREADS
2794 result = MoveFileA(p1, p2);
2795 Py_END_ALLOW_THREADS
2796 if (!result)
2797 return win32_error("rename", NULL);
2798 Py_INCREF(Py_None);
2799 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002800#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002801 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002802#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002803}
2804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002805
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002807"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002808Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002809
Barry Warsaw53699e91996-12-10 23:23:01 +00002810static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002811posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002812{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002813#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002814 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002815#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002816 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002817#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002818}
2819
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002821PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002822"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002823Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002824
Barry Warsaw53699e91996-12-10 23:23:01 +00002825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002826posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002827{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002828#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002829 return posix_do_stat(self, args, "et:stat", STAT, "u:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002830#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002831 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002833}
2834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002836#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002838"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002840
Barry Warsaw53699e91996-12-10 23:23:01 +00002841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002842posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002844 char *command;
2845 long sts;
2846 if (!PyArg_ParseTuple(args, "s:system", &command))
2847 return NULL;
2848 Py_BEGIN_ALLOW_THREADS
2849 sts = system(command);
2850 Py_END_ALLOW_THREADS
2851 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002852}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002853#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002856PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002857"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002858Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002859
Barry Warsaw53699e91996-12-10 23:23:01 +00002860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002861posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002862{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002863 int i;
2864 if (!PyArg_ParseTuple(args, "i:umask", &i))
2865 return NULL;
2866 i = (int)umask(i);
2867 if (i < 0)
2868 return posix_error();
2869 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002870}
2871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002872
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002873PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002874"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002875Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002877PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002878"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002880
Barry Warsaw53699e91996-12-10 23:23:01 +00002881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002882posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002883{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002884#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002885 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002886#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002887 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002888#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002889}
2890
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002891
Guido van Rossumb6775db1994-08-01 11:34:53 +00002892#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002896
Barry Warsaw53699e91996-12-10 23:23:01 +00002897static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002898posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002899{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002900 struct utsname u;
2901 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002902
Victor Stinnerd6f85422010-05-05 23:33:33 +00002903 Py_BEGIN_ALLOW_THREADS
2904 res = uname(&u);
2905 Py_END_ALLOW_THREADS
2906 if (res < 0)
2907 return posix_error();
2908 return Py_BuildValue("(sssss)",
2909 u.sysname,
2910 u.nodename,
2911 u.release,
2912 u.version,
2913 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002914}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002915#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002916
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002917static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002918extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002919{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002920 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002921 if (PyFloat_Check(t)) {
2922 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002923 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002924 if (!intobj)
2925 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002926#if SIZEOF_TIME_T > SIZEOF_LONG
2927 intval = PyInt_AsUnsignedLongLongMask(intobj);
2928#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002929 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002930#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002931 Py_DECREF(intobj);
2932 if (intval == -1 && PyErr_Occurred())
2933 return -1;
2934 *sec = intval;
2935 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2936 if (*usec < 0)
2937 /* If rounding gave us a negative number,
2938 truncate. */
2939 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002940 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002941 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002942#if SIZEOF_TIME_T > SIZEOF_LONG
2943 intval = PyInt_AsUnsignedLongLongMask(t);
2944#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002945 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002946#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002947 if (intval == -1 && PyErr_Occurred())
2948 return -1;
2949 *sec = intval;
2950 *usec = 0;
2951 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002952}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002953
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002955"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002956utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002957Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002958second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Barry Warsaw53699e91996-12-10 23:23:01 +00002960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002961posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002962{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002963#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002964 PyObject *arg;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002965 wchar_t *wpath = NULL;
2966 char *apath = NULL;
2967 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002968 time_t atimesec, mtimesec;
2969 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002970 FILETIME atime, mtime;
2971 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002972
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002973 if (PyArg_ParseTuple(args, "uO|:utime", &wpath, &arg)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002974 Py_BEGIN_ALLOW_THREADS
2975 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2976 NULL, OPEN_EXISTING,
2977 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2978 Py_END_ALLOW_THREADS
2979 if (hFile == INVALID_HANDLE_VALUE)
2980 return win32_error_unicode("utime", wpath);
2981 } else
2982 /* Drop the argument parsing error as narrow strings
2983 are also valid. */
2984 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002985
Victor Stinnerd6f85422010-05-05 23:33:33 +00002986 if (!wpath) {
2987 if (!PyArg_ParseTuple(args, "etO:utime",
2988 Py_FileSystemDefaultEncoding, &apath, &arg))
2989 return NULL;
2990 Py_BEGIN_ALLOW_THREADS
2991 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2992 NULL, OPEN_EXISTING,
2993 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2994 Py_END_ALLOW_THREADS
2995 if (hFile == INVALID_HANDLE_VALUE) {
2996 win32_error("utime", apath);
2997 PyMem_Free(apath);
2998 return NULL;
2999 }
3000 PyMem_Free(apath);
3001 }
3002
3003 if (arg == Py_None) {
3004 SYSTEMTIME now;
3005 GetSystemTime(&now);
3006 if (!SystemTimeToFileTime(&now, &mtime) ||
3007 !SystemTimeToFileTime(&now, &atime)) {
3008 win32_error("utime", NULL);
3009 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00003010 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003011 }
3012 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3013 PyErr_SetString(PyExc_TypeError,
3014 "utime() arg 2 must be a tuple (atime, mtime)");
3015 goto done;
3016 }
3017 else {
3018 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3019 &atimesec, &ausec) == -1)
3020 goto done;
3021 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3022 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3023 &mtimesec, &musec) == -1)
3024 goto done;
3025 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3026 }
3027 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3028 /* Avoid putting the file name into the error here,
3029 as that may confuse the user into believing that
3030 something is wrong with the file, when it also
3031 could be the time stamp that gives a problem. */
3032 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00003033 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003034 }
3035 Py_INCREF(Py_None);
3036 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003037done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003038 CloseHandle(hFile);
3039 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003040#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003041
Victor Stinnerd6f85422010-05-05 23:33:33 +00003042 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00003043 time_t atime, mtime;
3044 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003045 int res;
3046 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003047
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003048#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003049 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003050#define ATIME buf[0].tv_sec
3051#define MTIME buf[1].tv_sec
3052#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003053/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003054 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003055#define ATIME buf.actime
3056#define MTIME buf.modtime
3057#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003058#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003059 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003060#define ATIME buf[0]
3061#define MTIME buf[1]
3062#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003063#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003064
Mark Hammond817c9292003-12-03 01:22:38 +00003065
Victor Stinnerd6f85422010-05-05 23:33:33 +00003066 if (!PyArg_ParseTuple(args, "etO:utime",
3067 Py_FileSystemDefaultEncoding, &path, &arg))
3068 return NULL;
3069 if (arg == Py_None) {
3070 /* optional time values not given */
3071 Py_BEGIN_ALLOW_THREADS
3072 res = utime(path, NULL);
3073 Py_END_ALLOW_THREADS
3074 }
3075 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3076 PyErr_SetString(PyExc_TypeError,
3077 "utime() arg 2 must be a tuple (atime, mtime)");
3078 PyMem_Free(path);
3079 return NULL;
3080 }
3081 else {
3082 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3083 &atime, &ausec) == -1) {
3084 PyMem_Free(path);
3085 return NULL;
3086 }
3087 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3088 &mtime, &musec) == -1) {
3089 PyMem_Free(path);
3090 return NULL;
3091 }
3092 ATIME = atime;
3093 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003094#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00003095 buf[0].tv_usec = ausec;
3096 buf[1].tv_usec = musec;
3097 Py_BEGIN_ALLOW_THREADS
3098 res = utimes(path, buf);
3099 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003100#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003101 Py_BEGIN_ALLOW_THREADS
3102 res = utime(path, UTIME_ARG);
3103 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003104#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003105 }
3106 if (res < 0) {
3107 return posix_error_with_allocated_filename(path);
3108 }
3109 PyMem_Free(path);
3110 Py_INCREF(Py_None);
3111 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003112#undef UTIME_ARG
3113#undef ATIME
3114#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003115#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003116}
3117
Guido van Rossum85e3b011991-06-03 12:42:10 +00003118
Guido van Rossum3b066191991-06-04 19:40:25 +00003119/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003121PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003122"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003123Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003124
Barry Warsaw53699e91996-12-10 23:23:01 +00003125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003126posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003127{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003128 int sts;
3129 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3130 return NULL;
3131 _exit(sts);
3132 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003133}
3134
Martin v. Löwis114619e2002-10-07 06:44:21 +00003135#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3136static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003137free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003138{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003139 Py_ssize_t i;
3140 for (i = 0; i < count; i++)
3141 PyMem_Free(array[i]);
3142 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003143}
3144#endif
3145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003146
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003147#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003148PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003149"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150Execute an executable path with arguments, replacing current process.\n\
3151\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003152 path: path of executable file\n\
3153 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154
Barry Warsaw53699e91996-12-10 23:23:01 +00003155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003156posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003157{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003158 char *path;
3159 PyObject *argv;
3160 char **argvlist;
3161 Py_ssize_t i, argc;
3162 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003163
Victor Stinnerd6f85422010-05-05 23:33:33 +00003164 /* execv has two arguments: (path, argv), where
3165 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003166
Victor Stinnerd6f85422010-05-05 23:33:33 +00003167 if (!PyArg_ParseTuple(args, "etO:execv",
3168 Py_FileSystemDefaultEncoding,
3169 &path, &argv))
3170 return NULL;
3171 if (PyList_Check(argv)) {
3172 argc = PyList_Size(argv);
3173 getitem = PyList_GetItem;
3174 }
3175 else if (PyTuple_Check(argv)) {
3176 argc = PyTuple_Size(argv);
3177 getitem = PyTuple_GetItem;
3178 }
3179 else {
3180 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3181 PyMem_Free(path);
3182 return NULL;
3183 }
3184 if (argc < 1) {
3185 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3186 PyMem_Free(path);
3187 return NULL;
3188 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003189
Victor Stinnerd6f85422010-05-05 23:33:33 +00003190 argvlist = PyMem_NEW(char *, argc+1);
3191 if (argvlist == NULL) {
3192 PyMem_Free(path);
3193 return PyErr_NoMemory();
3194 }
3195 for (i = 0; i < argc; i++) {
3196 if (!PyArg_Parse((*getitem)(argv, i), "et",
3197 Py_FileSystemDefaultEncoding,
3198 &argvlist[i])) {
3199 free_string_array(argvlist, i);
3200 PyErr_SetString(PyExc_TypeError,
3201 "execv() arg 2 must contain only strings");
3202 PyMem_Free(path);
3203 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003204
Victor Stinnerd6f85422010-05-05 23:33:33 +00003205 }
3206 }
3207 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003208
Victor Stinnerd6f85422010-05-05 23:33:33 +00003209 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003210
Victor Stinnerd6f85422010-05-05 23:33:33 +00003211 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003212
Victor Stinnerd6f85422010-05-05 23:33:33 +00003213 free_string_array(argvlist, argc);
3214 PyMem_Free(path);
3215 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003216}
3217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003218
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003219PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003220"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221Execute a path with arguments and environment, replacing current process.\n\
3222\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003223 path: path of executable file\n\
3224 args: tuple or list of arguments\n\
3225 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003226
Barry Warsaw53699e91996-12-10 23:23:01 +00003227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003228posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003229{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003230 char *path;
3231 PyObject *argv, *env;
3232 char **argvlist;
3233 char **envlist;
3234 PyObject *key, *val, *keys=NULL, *vals=NULL;
3235 Py_ssize_t i, pos, argc, envc;
3236 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3237 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003238
Victor Stinnerd6f85422010-05-05 23:33:33 +00003239 /* execve has three arguments: (path, argv, env), where
3240 argv is a list or tuple of strings and env is a dictionary
3241 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003242
Victor Stinnerd6f85422010-05-05 23:33:33 +00003243 if (!PyArg_ParseTuple(args, "etOO:execve",
3244 Py_FileSystemDefaultEncoding,
3245 &path, &argv, &env))
3246 return NULL;
3247 if (PyList_Check(argv)) {
3248 argc = PyList_Size(argv);
3249 getitem = PyList_GetItem;
3250 }
3251 else if (PyTuple_Check(argv)) {
3252 argc = PyTuple_Size(argv);
3253 getitem = PyTuple_GetItem;
3254 }
3255 else {
3256 PyErr_SetString(PyExc_TypeError,
3257 "execve() arg 2 must be a tuple or list");
3258 goto fail_0;
3259 }
3260 if (!PyMapping_Check(env)) {
3261 PyErr_SetString(PyExc_TypeError,
3262 "execve() arg 3 must be a mapping object");
3263 goto fail_0;
3264 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003265
Victor Stinnerd6f85422010-05-05 23:33:33 +00003266 argvlist = PyMem_NEW(char *, argc+1);
3267 if (argvlist == NULL) {
3268 PyErr_NoMemory();
3269 goto fail_0;
3270 }
3271 for (i = 0; i < argc; i++) {
3272 if (!PyArg_Parse((*getitem)(argv, i),
3273 "et;execve() arg 2 must contain only strings",
3274 Py_FileSystemDefaultEncoding,
3275 &argvlist[i]))
3276 {
3277 lastarg = i;
3278 goto fail_1;
3279 }
3280 }
3281 lastarg = argc;
3282 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003283
Victor Stinnerd6f85422010-05-05 23:33:33 +00003284 i = PyMapping_Size(env);
3285 if (i < 0)
3286 goto fail_1;
3287 envlist = PyMem_NEW(char *, i + 1);
3288 if (envlist == NULL) {
3289 PyErr_NoMemory();
3290 goto fail_1;
3291 }
3292 envc = 0;
3293 keys = PyMapping_Keys(env);
3294 vals = PyMapping_Values(env);
3295 if (!keys || !vals)
3296 goto fail_2;
3297 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3298 PyErr_SetString(PyExc_TypeError,
3299 "execve(): env.keys() or env.values() is not a list");
3300 goto fail_2;
3301 }
Tim Peters5aa91602002-01-30 05:46:57 +00003302
Victor Stinnerd6f85422010-05-05 23:33:33 +00003303 for (pos = 0; pos < i; pos++) {
3304 char *p, *k, *v;
3305 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003306
Victor Stinnerd6f85422010-05-05 23:33:33 +00003307 key = PyList_GetItem(keys, pos);
3308 val = PyList_GetItem(vals, pos);
3309 if (!key || !val)
3310 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003311
Victor Stinnerd6f85422010-05-05 23:33:33 +00003312 if (!PyArg_Parse(
3313 key,
3314 "s;execve() arg 3 contains a non-string key",
3315 &k) ||
3316 !PyArg_Parse(
3317 val,
3318 "s;execve() arg 3 contains a non-string value",
3319 &v))
3320 {
3321 goto fail_2;
3322 }
Serhiy Storchaka9dda2ca2017-06-24 11:49:00 +03003323 /* Search from index 1 because on Windows starting '=' is allowed for
3324 defining hidden environment variables. */
3325 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3326 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3327 goto fail_2;
3328 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003329
3330#if defined(PYOS_OS2)
3331 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3332 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3333#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003334 len = PyString_Size(key) + PyString_Size(val) + 2;
3335 p = PyMem_NEW(char, len);
3336 if (p == NULL) {
3337 PyErr_NoMemory();
3338 goto fail_2;
3339 }
3340 PyOS_snprintf(p, len, "%s=%s", k, v);
3341 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003342#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003343 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003344#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003345 }
3346 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003347
Victor Stinnerd6f85422010-05-05 23:33:33 +00003348 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003349
Victor Stinnerd6f85422010-05-05 23:33:33 +00003350 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003351
Victor Stinnerd6f85422010-05-05 23:33:33 +00003352 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003353
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003354 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003355 while (--envc >= 0)
3356 PyMem_DEL(envlist[envc]);
3357 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003358 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003359 free_string_array(argvlist, lastarg);
3360 Py_XDECREF(vals);
3361 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003362 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003363 PyMem_Free(path);
3364 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003365}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003366#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003368
Guido van Rossuma1065681999-01-25 23:20:23 +00003369#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003370PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003371"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003372Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003373\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003374 mode: mode of process creation\n\
3375 path: path of executable file\n\
3376 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003377
3378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003379posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003380{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003381 char *path;
3382 PyObject *argv;
3383 char **argvlist;
3384 int mode, i;
3385 Py_ssize_t argc;
3386 Py_intptr_t spawnval;
3387 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003388
Victor Stinnerd6f85422010-05-05 23:33:33 +00003389 /* spawnv has three arguments: (mode, path, argv), where
3390 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003391
Victor Stinnerd6f85422010-05-05 23:33:33 +00003392 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3393 Py_FileSystemDefaultEncoding,
3394 &path, &argv))
3395 return NULL;
3396 if (PyList_Check(argv)) {
3397 argc = PyList_Size(argv);
3398 getitem = PyList_GetItem;
3399 }
3400 else if (PyTuple_Check(argv)) {
3401 argc = PyTuple_Size(argv);
3402 getitem = PyTuple_GetItem;
3403 }
3404 else {
3405 PyErr_SetString(PyExc_TypeError,
3406 "spawnv() arg 2 must be a tuple or list");
3407 PyMem_Free(path);
3408 return NULL;
3409 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003410
Victor Stinnerd6f85422010-05-05 23:33:33 +00003411 argvlist = PyMem_NEW(char *, argc+1);
3412 if (argvlist == NULL) {
3413 PyMem_Free(path);
3414 return PyErr_NoMemory();
3415 }
3416 for (i = 0; i < argc; i++) {
3417 if (!PyArg_Parse((*getitem)(argv, i), "et",
3418 Py_FileSystemDefaultEncoding,
3419 &argvlist[i])) {
3420 free_string_array(argvlist, i);
3421 PyErr_SetString(
3422 PyExc_TypeError,
3423 "spawnv() arg 2 must contain only strings");
3424 PyMem_Free(path);
3425 return NULL;
3426 }
3427 }
3428 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003429
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003430#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003431 Py_BEGIN_ALLOW_THREADS
3432 spawnval = spawnv(mode, path, argvlist);
3433 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003434#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003435 if (mode == _OLD_P_OVERLAY)
3436 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003437
Victor Stinnerd6f85422010-05-05 23:33:33 +00003438 Py_BEGIN_ALLOW_THREADS
3439 spawnval = _spawnv(mode, path, argvlist);
3440 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003441#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003442
Victor Stinnerd6f85422010-05-05 23:33:33 +00003443 free_string_array(argvlist, argc);
3444 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003445
Victor Stinnerd6f85422010-05-05 23:33:33 +00003446 if (spawnval == -1)
3447 return posix_error();
3448 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003449#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003450 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003451#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003452 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003453#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003454}
3455
3456
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003457PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003458"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003459Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003460\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003461 mode: mode of process creation\n\
3462 path: path of executable file\n\
3463 args: tuple or list of arguments\n\
3464 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003465
3466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003467posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003468{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003469 char *path;
3470 PyObject *argv, *env;
3471 char **argvlist;
3472 char **envlist;
3473 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3474 int mode, pos, envc;
3475 Py_ssize_t argc, i;
3476 Py_intptr_t spawnval;
3477 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3478 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003479
Victor Stinnerd6f85422010-05-05 23:33:33 +00003480 /* spawnve has four arguments: (mode, path, argv, env), where
3481 argv is a list or tuple of strings and env is a dictionary
3482 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003483
Victor Stinnerd6f85422010-05-05 23:33:33 +00003484 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3485 Py_FileSystemDefaultEncoding,
3486 &path, &argv, &env))
3487 return NULL;
3488 if (PyList_Check(argv)) {
3489 argc = PyList_Size(argv);
3490 getitem = PyList_GetItem;
3491 }
3492 else if (PyTuple_Check(argv)) {
3493 argc = PyTuple_Size(argv);
3494 getitem = PyTuple_GetItem;
3495 }
3496 else {
3497 PyErr_SetString(PyExc_TypeError,
3498 "spawnve() arg 2 must be a tuple or list");
3499 goto fail_0;
3500 }
3501 if (!PyMapping_Check(env)) {
3502 PyErr_SetString(PyExc_TypeError,
3503 "spawnve() arg 3 must be a mapping object");
3504 goto fail_0;
3505 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003506
Victor Stinnerd6f85422010-05-05 23:33:33 +00003507 argvlist = PyMem_NEW(char *, argc+1);
3508 if (argvlist == NULL) {
3509 PyErr_NoMemory();
3510 goto fail_0;
3511 }
3512 for (i = 0; i < argc; i++) {
3513 if (!PyArg_Parse((*getitem)(argv, i),
3514 "et;spawnve() arg 2 must contain only strings",
3515 Py_FileSystemDefaultEncoding,
3516 &argvlist[i]))
3517 {
3518 lastarg = i;
3519 goto fail_1;
3520 }
3521 }
3522 lastarg = argc;
3523 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003524
Victor Stinnerd6f85422010-05-05 23:33:33 +00003525 i = PyMapping_Size(env);
3526 if (i < 0)
3527 goto fail_1;
3528 envlist = PyMem_NEW(char *, i + 1);
3529 if (envlist == NULL) {
3530 PyErr_NoMemory();
3531 goto fail_1;
3532 }
3533 envc = 0;
3534 keys = PyMapping_Keys(env);
3535 vals = PyMapping_Values(env);
3536 if (!keys || !vals)
3537 goto fail_2;
3538 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3539 PyErr_SetString(PyExc_TypeError,
3540 "spawnve(): env.keys() or env.values() is not a list");
3541 goto fail_2;
3542 }
Tim Peters5aa91602002-01-30 05:46:57 +00003543
Victor Stinnerd6f85422010-05-05 23:33:33 +00003544 for (pos = 0; pos < i; pos++) {
3545 char *p, *k, *v;
3546 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003547
Victor Stinnerd6f85422010-05-05 23:33:33 +00003548 key = PyList_GetItem(keys, pos);
3549 val = PyList_GetItem(vals, pos);
3550 if (!key || !val)
3551 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003552
Victor Stinnerd6f85422010-05-05 23:33:33 +00003553 if (!PyArg_Parse(
3554 key,
3555 "s;spawnve() arg 3 contains a non-string key",
3556 &k) ||
3557 !PyArg_Parse(
3558 val,
3559 "s;spawnve() arg 3 contains a non-string value",
3560 &v))
3561 {
3562 goto fail_2;
3563 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003564 /* Search from index 1 because on Windows starting '=' is allowed for
3565 defining hidden environment variables. */
3566 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3567 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3568 goto fail_2;
3569 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003570 len = PyString_Size(key) + PyString_Size(val) + 2;
3571 p = PyMem_NEW(char, len);
3572 if (p == NULL) {
3573 PyErr_NoMemory();
3574 goto fail_2;
3575 }
3576 PyOS_snprintf(p, len, "%s=%s", k, v);
3577 envlist[envc++] = p;
3578 }
3579 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003580
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003581#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003582 Py_BEGIN_ALLOW_THREADS
3583 spawnval = spawnve(mode, path, argvlist, envlist);
3584 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003585#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003586 if (mode == _OLD_P_OVERLAY)
3587 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003588
Victor Stinnerd6f85422010-05-05 23:33:33 +00003589 Py_BEGIN_ALLOW_THREADS
3590 spawnval = _spawnve(mode, path, argvlist, envlist);
3591 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003592#endif
Tim Peters25059d32001-12-07 20:35:43 +00003593
Victor Stinnerd6f85422010-05-05 23:33:33 +00003594 if (spawnval == -1)
3595 (void) posix_error();
3596 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003597#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003598 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003599#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003600 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003601#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003602
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003603 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003604 while (--envc >= 0)
3605 PyMem_DEL(envlist[envc]);
3606 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003607 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003608 free_string_array(argvlist, lastarg);
3609 Py_XDECREF(vals);
3610 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003611 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003612 PyMem_Free(path);
3613 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003614}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003615
3616/* OS/2 supports spawnvp & spawnvpe natively */
3617#if defined(PYOS_OS2)
3618PyDoc_STRVAR(posix_spawnvp__doc__,
3619"spawnvp(mode, file, args)\n\n\
3620Execute the program 'file' in a new process, using the environment\n\
3621search path to find the file.\n\
3622\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 mode: mode of process creation\n\
3624 file: executable file name\n\
3625 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003626
3627static PyObject *
3628posix_spawnvp(PyObject *self, PyObject *args)
3629{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003630 char *path;
3631 PyObject *argv;
3632 char **argvlist;
3633 int mode, i, argc;
3634 Py_intptr_t spawnval;
3635 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003636
Victor Stinnerd6f85422010-05-05 23:33:33 +00003637 /* spawnvp has three arguments: (mode, path, argv), where
3638 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003639
Victor Stinnerd6f85422010-05-05 23:33:33 +00003640 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3641 Py_FileSystemDefaultEncoding,
3642 &path, &argv))
3643 return NULL;
3644 if (PyList_Check(argv)) {
3645 argc = PyList_Size(argv);
3646 getitem = PyList_GetItem;
3647 }
3648 else if (PyTuple_Check(argv)) {
3649 argc = PyTuple_Size(argv);
3650 getitem = PyTuple_GetItem;
3651 }
3652 else {
3653 PyErr_SetString(PyExc_TypeError,
3654 "spawnvp() arg 2 must be a tuple or list");
3655 PyMem_Free(path);
3656 return NULL;
3657 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003658
Victor Stinnerd6f85422010-05-05 23:33:33 +00003659 argvlist = PyMem_NEW(char *, argc+1);
3660 if (argvlist == NULL) {
3661 PyMem_Free(path);
3662 return PyErr_NoMemory();
3663 }
3664 for (i = 0; i < argc; i++) {
3665 if (!PyArg_Parse((*getitem)(argv, i), "et",
3666 Py_FileSystemDefaultEncoding,
3667 &argvlist[i])) {
3668 free_string_array(argvlist, i);
3669 PyErr_SetString(
3670 PyExc_TypeError,
3671 "spawnvp() arg 2 must contain only strings");
3672 PyMem_Free(path);
3673 return NULL;
3674 }
3675 }
3676 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003677
Victor Stinnerd6f85422010-05-05 23:33:33 +00003678 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003679#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003680 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003681#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003682 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003683#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003684 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003685
Victor Stinnerd6f85422010-05-05 23:33:33 +00003686 free_string_array(argvlist, argc);
3687 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003688
Victor Stinnerd6f85422010-05-05 23:33:33 +00003689 if (spawnval == -1)
3690 return posix_error();
3691 else
3692 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003693}
3694
3695
3696PyDoc_STRVAR(posix_spawnvpe__doc__,
3697"spawnvpe(mode, file, args, env)\n\n\
3698Execute the program 'file' in a new process, using the environment\n\
3699search path to find the file.\n\
3700\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003701 mode: mode of process creation\n\
3702 file: executable file name\n\
3703 args: tuple or list of arguments\n\
3704 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003705
3706static PyObject *
3707posix_spawnvpe(PyObject *self, PyObject *args)
3708{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003709 char *path;
3710 PyObject *argv, *env;
3711 char **argvlist;
3712 char **envlist;
3713 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3714 int mode, i, pos, argc, envc;
3715 Py_intptr_t spawnval;
3716 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3717 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003718
Victor Stinnerd6f85422010-05-05 23:33:33 +00003719 /* spawnvpe has four arguments: (mode, path, argv, env), where
3720 argv is a list or tuple of strings and env is a dictionary
3721 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003722
Victor Stinnerd6f85422010-05-05 23:33:33 +00003723 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3724 Py_FileSystemDefaultEncoding,
3725 &path, &argv, &env))
3726 return NULL;
3727 if (PyList_Check(argv)) {
3728 argc = PyList_Size(argv);
3729 getitem = PyList_GetItem;
3730 }
3731 else if (PyTuple_Check(argv)) {
3732 argc = PyTuple_Size(argv);
3733 getitem = PyTuple_GetItem;
3734 }
3735 else {
3736 PyErr_SetString(PyExc_TypeError,
3737 "spawnvpe() arg 2 must be a tuple or list");
3738 goto fail_0;
3739 }
3740 if (!PyMapping_Check(env)) {
3741 PyErr_SetString(PyExc_TypeError,
3742 "spawnvpe() arg 3 must be a mapping object");
3743 goto fail_0;
3744 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003745
Victor Stinnerd6f85422010-05-05 23:33:33 +00003746 argvlist = PyMem_NEW(char *, argc+1);
3747 if (argvlist == NULL) {
3748 PyErr_NoMemory();
3749 goto fail_0;
3750 }
3751 for (i = 0; i < argc; i++) {
3752 if (!PyArg_Parse((*getitem)(argv, i),
3753 "et;spawnvpe() arg 2 must contain only strings",
3754 Py_FileSystemDefaultEncoding,
3755 &argvlist[i]))
3756 {
3757 lastarg = i;
3758 goto fail_1;
3759 }
3760 }
3761 lastarg = argc;
3762 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003763
Victor Stinnerd6f85422010-05-05 23:33:33 +00003764 i = PyMapping_Size(env);
3765 if (i < 0)
3766 goto fail_1;
3767 envlist = PyMem_NEW(char *, i + 1);
3768 if (envlist == NULL) {
3769 PyErr_NoMemory();
3770 goto fail_1;
3771 }
3772 envc = 0;
3773 keys = PyMapping_Keys(env);
3774 vals = PyMapping_Values(env);
3775 if (!keys || !vals)
3776 goto fail_2;
3777 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3778 PyErr_SetString(PyExc_TypeError,
3779 "spawnvpe(): env.keys() or env.values() is not a list");
3780 goto fail_2;
3781 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003782
Victor Stinnerd6f85422010-05-05 23:33:33 +00003783 for (pos = 0; pos < i; pos++) {
3784 char *p, *k, *v;
3785 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003786
Victor Stinnerd6f85422010-05-05 23:33:33 +00003787 key = PyList_GetItem(keys, pos);
3788 val = PyList_GetItem(vals, pos);
3789 if (!key || !val)
3790 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003791
Victor Stinnerd6f85422010-05-05 23:33:33 +00003792 if (!PyArg_Parse(
3793 key,
3794 "s;spawnvpe() arg 3 contains a non-string key",
3795 &k) ||
3796 !PyArg_Parse(
3797 val,
3798 "s;spawnvpe() arg 3 contains a non-string value",
3799 &v))
3800 {
3801 goto fail_2;
3802 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003803 /* Search from index 1 because on Windows starting '=' is allowed for
3804 defining hidden environment variables. */
3805 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3806 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3807 goto fail_2;
3808 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003809 len = PyString_Size(key) + PyString_Size(val) + 2;
3810 p = PyMem_NEW(char, len);
3811 if (p == NULL) {
3812 PyErr_NoMemory();
3813 goto fail_2;
3814 }
3815 PyOS_snprintf(p, len, "%s=%s", k, v);
3816 envlist[envc++] = p;
3817 }
3818 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003819
Victor Stinnerd6f85422010-05-05 23:33:33 +00003820 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003821#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003822 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003823#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003824 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003825#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003826 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003827
Victor Stinnerd6f85422010-05-05 23:33:33 +00003828 if (spawnval == -1)
3829 (void) posix_error();
3830 else
3831 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003832
3833 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003834 while (--envc >= 0)
3835 PyMem_DEL(envlist[envc]);
3836 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003837 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003838 free_string_array(argvlist, lastarg);
3839 Py_XDECREF(vals);
3840 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003841 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003842 PyMem_Free(path);
3843 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003844}
3845#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003846#endif /* HAVE_SPAWNV */
3847
3848
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003849#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003851"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003852Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3853\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003854Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003855
3856static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003857posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003858{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003859 pid_t pid;
3860 int result = 0;
3861 _PyImport_AcquireLock();
3862 pid = fork1();
3863 if (pid == 0) {
3864 /* child: this clobbers and resets the import lock. */
3865 PyOS_AfterFork();
3866 } else {
3867 /* parent: release the import lock. */
3868 result = _PyImport_ReleaseLock();
3869 }
3870 if (pid == -1)
3871 return posix_error();
3872 if (result < 0) {
3873 /* Don't clobber the OSError if the fork failed. */
3874 PyErr_SetString(PyExc_RuntimeError,
3875 "not holding the import lock");
3876 return NULL;
3877 }
3878 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003879}
3880#endif
3881
3882
Guido van Rossumad0ee831995-03-01 10:34:45 +00003883#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003884PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003885"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003886Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Barry Warsaw53699e91996-12-10 23:23:01 +00003889static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003890posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003891{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003892 pid_t pid;
3893 int result = 0;
3894 _PyImport_AcquireLock();
3895 pid = fork();
3896 if (pid == 0) {
3897 /* child: this clobbers and resets the import lock. */
3898 PyOS_AfterFork();
3899 } else {
3900 /* parent: release the import lock. */
3901 result = _PyImport_ReleaseLock();
3902 }
3903 if (pid == -1)
3904 return posix_error();
3905 if (result < 0) {
3906 /* Don't clobber the OSError if the fork failed. */
3907 PyErr_SetString(PyExc_RuntimeError,
3908 "not holding the import lock");
3909 return NULL;
3910 }
3911 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003912}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003913#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003914
Neal Norwitzb59798b2003-03-21 01:43:31 +00003915/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003916/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3917#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003918#define DEV_PTY_FILE "/dev/ptc"
3919#define HAVE_DEV_PTMX
3920#else
3921#define DEV_PTY_FILE "/dev/ptmx"
3922#endif
3923
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003924#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003925#ifdef HAVE_PTY_H
3926#include <pty.h>
3927#else
3928#ifdef HAVE_LIBUTIL_H
3929#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003930#else
3931#ifdef HAVE_UTIL_H
3932#include <util.h>
3933#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003934#endif /* HAVE_LIBUTIL_H */
3935#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003936#ifdef HAVE_STROPTS_H
3937#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003938#endif
3939#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003940
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003941#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003942PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003943"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003944Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003945
3946static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003947posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003948{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003949 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003950#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003951 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003952#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003953#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003954 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003955#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003956 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003957#endif
3958#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003959
Thomas Wouters70c21a12000-07-14 14:28:33 +00003960#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003961 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3962 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003963#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003964 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3965 if (slave_name == NULL)
3966 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003967
Victor Stinnerd6f85422010-05-05 23:33:33 +00003968 slave_fd = open(slave_name, O_RDWR);
3969 if (slave_fd < 0)
3970 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003971#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003972 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3973 if (master_fd < 0)
3974 return posix_error();
3975 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3976 /* change permission of slave */
3977 if (grantpt(master_fd) < 0) {
3978 PyOS_setsig(SIGCHLD, sig_saved);
3979 return posix_error();
3980 }
3981 /* unlock slave */
3982 if (unlockpt(master_fd) < 0) {
3983 PyOS_setsig(SIGCHLD, sig_saved);
3984 return posix_error();
3985 }
3986 PyOS_setsig(SIGCHLD, sig_saved);
3987 slave_name = ptsname(master_fd); /* get name of slave */
3988 if (slave_name == NULL)
3989 return posix_error();
3990 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3991 if (slave_fd < 0)
3992 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003993#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003994 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3995 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003996#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003998#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003999#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004000#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004001
Victor Stinnerd6f85422010-05-05 23:33:33 +00004002 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004003
Fred Drake8cef4cf2000-06-28 16:40:38 +00004004}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004005#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004006
4007#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004009"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004010Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4011Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004013
4014static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004015posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004016{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004017 int master_fd = -1, result = 0;
4018 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004019
Victor Stinnerd6f85422010-05-05 23:33:33 +00004020 _PyImport_AcquireLock();
4021 pid = forkpty(&master_fd, NULL, NULL, NULL);
4022 if (pid == 0) {
4023 /* child: this clobbers and resets the import lock. */
4024 PyOS_AfterFork();
4025 } else {
4026 /* parent: release the import lock. */
4027 result = _PyImport_ReleaseLock();
4028 }
4029 if (pid == -1)
4030 return posix_error();
4031 if (result < 0) {
4032 /* Don't clobber the OSError if the fork failed. */
4033 PyErr_SetString(PyExc_RuntimeError,
4034 "not holding the import lock");
4035 return NULL;
4036 }
4037 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004038}
4039#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004040
Guido van Rossumad0ee831995-03-01 10:34:45 +00004041#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004042PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004043"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004045
Barry Warsaw53699e91996-12-10 23:23:01 +00004046static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004047posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004048{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004049 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004050}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004051#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004053
Guido van Rossumad0ee831995-03-01 10:34:45 +00004054#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004055PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004056"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004058
Barry Warsaw53699e91996-12-10 23:23:01 +00004059static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004060posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004061{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004062 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004063}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004064#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004066
Guido van Rossumad0ee831995-03-01 10:34:45 +00004067#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004068PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004069"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004070Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004071
Barry Warsaw53699e91996-12-10 23:23:01 +00004072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004073posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004074{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004075 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004076}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004077#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004081"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004082Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004083
Barry Warsaw53699e91996-12-10 23:23:01 +00004084static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004085posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004086{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004087 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004088}
4089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004090
Fred Drakec9680921999-12-13 16:37:25 +00004091#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004092PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004093"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004094Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004095
4096static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004097posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004098{
4099 PyObject *result = NULL;
4100
Fred Drakec9680921999-12-13 16:37:25 +00004101#ifdef NGROUPS_MAX
4102#define MAX_GROUPS NGROUPS_MAX
4103#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004104 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004105#define MAX_GROUPS 64
4106#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004107 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004108
Victor Stinner59729ff2011-07-05 11:28:19 +02004109 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004110 * This is a helper variable to store the intermediate result when
4111 * that happens.
4112 *
4113 * To keep the code readable the OSX behaviour is unconditional,
4114 * according to the POSIX spec this should be safe on all unix-y
4115 * systems.
4116 */
4117 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004118 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004119
Ned Deily80743642013-08-01 21:19:09 -07004120#ifdef __APPLE__
4121 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4122 * there are more groups than can fit in grouplist. Therefore, on OS X
4123 * always first call getgroups with length 0 to get the actual number
4124 * of groups.
4125 */
4126 n = getgroups(0, NULL);
4127 if (n < 0) {
4128 return posix_error();
4129 } else if (n <= MAX_GROUPS) {
4130 /* groups will fit in existing array */
4131 alt_grouplist = grouplist;
4132 } else {
4133 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4134 if (alt_grouplist == NULL) {
4135 errno = EINVAL;
4136 return posix_error();
4137 }
4138 }
4139
4140 n = getgroups(n, alt_grouplist);
4141 if (n == -1) {
4142 if (alt_grouplist != grouplist) {
4143 PyMem_Free(alt_grouplist);
4144 }
4145 return posix_error();
4146 }
4147#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004148 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004149 if (n < 0) {
4150 if (errno == EINVAL) {
4151 n = getgroups(0, NULL);
4152 if (n == -1) {
4153 return posix_error();
4154 }
4155 if (n == 0) {
4156 /* Avoid malloc(0) */
4157 alt_grouplist = grouplist;
4158 } else {
4159 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4160 if (alt_grouplist == NULL) {
4161 errno = EINVAL;
4162 return posix_error();
4163 }
4164 n = getgroups(n, alt_grouplist);
4165 if (n == -1) {
4166 PyMem_Free(alt_grouplist);
4167 return posix_error();
4168 }
4169 }
4170 } else {
4171 return posix_error();
4172 }
4173 }
Ned Deily80743642013-08-01 21:19:09 -07004174#endif
4175
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004176 result = PyList_New(n);
4177 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004178 int i;
4179 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004180 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004181 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004182 Py_DECREF(result);
4183 result = NULL;
4184 break;
Fred Drakec9680921999-12-13 16:37:25 +00004185 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004186 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004187 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004188 }
4189
4190 if (alt_grouplist != grouplist) {
4191 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004192 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004193
Fred Drakec9680921999-12-13 16:37:25 +00004194 return result;
4195}
4196#endif
4197
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004198#ifdef HAVE_INITGROUPS
4199PyDoc_STRVAR(posix_initgroups__doc__,
4200"initgroups(username, gid) -> None\n\n\
4201Call the system initgroups() to initialize the group access list with all of\n\
4202the groups of which the specified username is a member, plus the specified\n\
4203group id.");
4204
4205static PyObject *
4206posix_initgroups(PyObject *self, PyObject *args)
4207{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004208 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004209#ifdef __APPLE__
4210 int gid;
4211#else
4212 gid_t gid;
4213#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004214
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004215#ifdef __APPLE__
4216 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4217 &gid))
4218#else
4219 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4220 _Py_Gid_Converter, &gid))
4221#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004222 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004223
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004224 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004225 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004226
Victor Stinnerd6f85422010-05-05 23:33:33 +00004227 Py_INCREF(Py_None);
4228 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004229}
4230#endif
4231
Martin v. Löwis606edc12002-06-13 21:09:11 +00004232#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004233PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004234"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004235Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004236
4237static PyObject *
4238posix_getpgid(PyObject *self, PyObject *args)
4239{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004240 pid_t pid, pgid;
4241 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4242 return NULL;
4243 pgid = getpgid(pid);
4244 if (pgid < 0)
4245 return posix_error();
4246 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004247}
4248#endif /* HAVE_GETPGID */
4249
4250
Guido van Rossumb6775db1994-08-01 11:34:53 +00004251#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004252PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004253"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004254Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004255
Barry Warsaw53699e91996-12-10 23:23:01 +00004256static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004257posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004258{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004259#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004260 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004261#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004262 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004263#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004264}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004265#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004266
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Guido van Rossumb6775db1994-08-01 11:34:53 +00004268#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004270"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004271Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004272
Barry Warsaw53699e91996-12-10 23:23:01 +00004273static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004274posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004275{
Guido van Rossum64933891994-10-20 21:56:42 +00004276#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004277 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004278#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004279 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004280#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004281 return posix_error();
4282 Py_INCREF(Py_None);
4283 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004284}
4285
Guido van Rossumb6775db1994-08-01 11:34:53 +00004286#endif /* HAVE_SETPGRP */
4287
Guido van Rossumad0ee831995-03-01 10:34:45 +00004288#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004289PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004290"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004291Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004292
Barry Warsaw53699e91996-12-10 23:23:01 +00004293static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004294posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004295{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004296 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004297}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004298#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Fred Drake12c6e2d1999-12-14 21:25:03 +00004301#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004302PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004303"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004304Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004305
4306static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004307posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004308{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004309 PyObject *result = NULL;
4310 char *name;
4311 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004312
Victor Stinnerd6f85422010-05-05 23:33:33 +00004313 errno = 0;
4314 name = getlogin();
4315 if (name == NULL) {
4316 if (errno)
4317 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004318 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004319 PyErr_SetString(PyExc_OSError,
4320 "unable to determine login name");
4321 }
4322 else
4323 result = PyString_FromString(name);
4324 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004325
Fred Drake12c6e2d1999-12-14 21:25:03 +00004326 return result;
4327}
4328#endif
4329
Guido van Rossumad0ee831995-03-01 10:34:45 +00004330#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004331PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004332"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004333Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004334
Barry Warsaw53699e91996-12-10 23:23:01 +00004335static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004336posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004337{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004338 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004339}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004340#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004342
Guido van Rossumad0ee831995-03-01 10:34:45 +00004343#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004344PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004345"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004346Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Barry Warsaw53699e91996-12-10 23:23:01 +00004348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004349posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004350{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004351 pid_t pid;
4352 int sig;
4353 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4354 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004355#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004356 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4357 APIRET rc;
4358 if ((rc = DosSendSignalException(pid, sig)) != 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 if (sig == XCPT_SIGNAL_KILLPROC) {
4362 APIRET rc;
4363 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004364 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004365
4366 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004367 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004368#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004369 if (kill(pid, sig) == -1)
4370 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004371#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004372 Py_INCREF(Py_None);
4373 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004374}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004375#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004376
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004377#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004378PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004379"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004380Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004381
4382static PyObject *
4383posix_killpg(PyObject *self, PyObject *args)
4384{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004385 int sig;
4386 pid_t pgid;
4387 /* XXX some man pages make the `pgid` parameter an int, others
4388 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4389 take the same type. Moreover, pid_t is always at least as wide as
4390 int (else compilation of this module fails), which is safe. */
4391 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4392 return NULL;
4393 if (killpg(pgid, sig) == -1)
4394 return posix_error();
4395 Py_INCREF(Py_None);
4396 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004397}
4398#endif
4399
Brian Curtine5aa8862010-04-02 23:26:06 +00004400#ifdef MS_WINDOWS
4401PyDoc_STRVAR(win32_kill__doc__,
4402"kill(pid, sig)\n\n\
4403Kill a process with a signal.");
4404
4405static PyObject *
4406win32_kill(PyObject *self, PyObject *args)
4407{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004408 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004409 DWORD pid, sig, err;
4410 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004411
Victor Stinnerd6f85422010-05-05 23:33:33 +00004412 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4413 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004414
Victor Stinnerd6f85422010-05-05 23:33:33 +00004415 /* Console processes which share a common console can be sent CTRL+C or
4416 CTRL+BREAK events, provided they handle said events. */
4417 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4418 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4419 err = GetLastError();
4420 return PyErr_SetFromWindowsErr(err);
4421 }
4422 else
4423 Py_RETURN_NONE;
4424 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004425
Victor Stinnerd6f85422010-05-05 23:33:33 +00004426 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4427 attempt to open and terminate the process. */
4428 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4429 if (handle == NULL) {
4430 err = GetLastError();
4431 return PyErr_SetFromWindowsErr(err);
4432 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004433
Victor Stinnerd6f85422010-05-05 23:33:33 +00004434 if (TerminateProcess(handle, sig) == 0) {
4435 err = GetLastError();
4436 result = PyErr_SetFromWindowsErr(err);
4437 } else {
4438 Py_INCREF(Py_None);
4439 result = Py_None;
4440 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004441
Victor Stinnerd6f85422010-05-05 23:33:33 +00004442 CloseHandle(handle);
4443 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004444}
Brian Curtincaea7e82011-06-08 19:29:53 -05004445
Brian Curtin5446f082011-06-09 10:00:42 -05004446PyDoc_STRVAR(posix__isdir__doc__,
4447"Return true if the pathname refers to an existing directory.");
4448
Brian Curtincaea7e82011-06-08 19:29:53 -05004449static PyObject *
4450posix__isdir(PyObject *self, PyObject *args)
4451{
Brian Curtincaea7e82011-06-08 19:29:53 -05004452 char *path;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004453 Py_UNICODE *wpath;
Brian Curtincaea7e82011-06-08 19:29:53 -05004454 DWORD attributes;
4455
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004456 if (PyArg_ParseTuple(args, "u|:_isdir", &wpath)) {
Brian Curtincaea7e82011-06-08 19:29:53 -05004457 attributes = GetFileAttributesW(wpath);
4458 if (attributes == INVALID_FILE_ATTRIBUTES)
4459 Py_RETURN_FALSE;
4460 goto check;
4461 }
4462 /* Drop the argument parsing error as narrow strings
4463 are also valid. */
4464 PyErr_Clear();
4465
4466 if (!PyArg_ParseTuple(args, "et:_isdir",
4467 Py_FileSystemDefaultEncoding, &path))
4468 return NULL;
4469
4470 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004471 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004472 if (attributes == INVALID_FILE_ATTRIBUTES)
4473 Py_RETURN_FALSE;
4474
4475check:
4476 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4477 Py_RETURN_TRUE;
4478 else
4479 Py_RETURN_FALSE;
4480}
Brian Curtine5aa8862010-04-02 23:26:06 +00004481#endif /* MS_WINDOWS */
4482
Guido van Rossumc0125471996-06-28 18:55:32 +00004483#ifdef HAVE_PLOCK
4484
4485#ifdef HAVE_SYS_LOCK_H
4486#include <sys/lock.h>
4487#endif
4488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004490"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Barry Warsaw53699e91996-12-10 23:23:01 +00004493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004494posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004495{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004496 int op;
4497 if (!PyArg_ParseTuple(args, "i:plock", &op))
4498 return NULL;
4499 if (plock(op) == -1)
4500 return posix_error();
4501 Py_INCREF(Py_None);
4502 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004503}
4504#endif
4505
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004506
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004507#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004508PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004509"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004510Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004511
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004512#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004513#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004514static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004515async_system(const char *command)
4516{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004517 char errormsg[256], args[1024];
4518 RESULTCODES rcodes;
4519 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004520
Victor Stinnerd6f85422010-05-05 23:33:33 +00004521 char *shell = getenv("COMSPEC");
4522 if (!shell)
4523 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004524
Victor Stinnerd6f85422010-05-05 23:33:33 +00004525 /* avoid overflowing the argument buffer */
4526 if (strlen(shell) + 3 + strlen(command) >= 1024)
4527 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004528
Victor Stinnerd6f85422010-05-05 23:33:33 +00004529 args[0] = '\0';
4530 strcat(args, shell);
4531 strcat(args, "/c ");
4532 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004533
Victor Stinnerd6f85422010-05-05 23:33:33 +00004534 /* execute asynchronously, inheriting the environment */
4535 rc = DosExecPgm(errormsg,
4536 sizeof(errormsg),
4537 EXEC_ASYNC,
4538 args,
4539 NULL,
4540 &rcodes,
4541 shell);
4542 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004543}
4544
Guido van Rossumd48f2521997-12-05 22:19:34 +00004545static FILE *
4546popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004547{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004548 int oldfd, tgtfd;
4549 HFILE pipeh[2];
4550 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004551
Victor Stinnerd6f85422010-05-05 23:33:33 +00004552 /* mode determines which of stdin or stdout is reconnected to
4553 * the pipe to the child
4554 */
4555 if (strchr(mode, 'r') != NULL) {
4556 tgt_fd = 1; /* stdout */
4557 } else if (strchr(mode, 'w')) {
4558 tgt_fd = 0; /* stdin */
4559 } else {
4560 *err = ERROR_INVALID_ACCESS;
4561 return NULL;
4562 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004563
Victor Stinnerd6f85422010-05-05 23:33:33 +00004564 /* setup the pipe */
4565 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4566 *err = rc;
4567 return NULL;
4568 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004569
Victor Stinnerd6f85422010-05-05 23:33:33 +00004570 /* prevent other threads accessing stdio */
4571 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004572
Victor Stinnerd6f85422010-05-05 23:33:33 +00004573 /* reconnect stdio and execute child */
4574 oldfd = dup(tgtfd);
4575 close(tgtfd);
4576 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4577 DosClose(pipeh[tgtfd]);
4578 rc = async_system(command);
4579 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004580
Victor Stinnerd6f85422010-05-05 23:33:33 +00004581 /* restore stdio */
4582 dup2(oldfd, tgtfd);
4583 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004584
Victor Stinnerd6f85422010-05-05 23:33:33 +00004585 /* allow other threads access to stdio */
4586 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004587
Victor Stinnerd6f85422010-05-05 23:33:33 +00004588 /* if execution of child was successful return file stream */
4589 if (rc == NO_ERROR)
4590 return fdopen(pipeh[1 - tgtfd], mode);
4591 else {
4592 DosClose(pipeh[1 - tgtfd]);
4593 *err = rc;
4594 return NULL;
4595 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004596}
4597
4598static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004599posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004600{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004601 char *name;
4602 char *mode = "r";
4603 int err, bufsize = -1;
4604 FILE *fp;
4605 PyObject *f;
4606 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4607 return NULL;
4608 Py_BEGIN_ALLOW_THREADS
4609 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4610 Py_END_ALLOW_THREADS
4611 if (fp == NULL)
4612 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004613
Victor Stinnerd6f85422010-05-05 23:33:33 +00004614 f = PyFile_FromFile(fp, name, mode, fclose);
4615 if (f != NULL)
4616 PyFile_SetBufSize(f, bufsize);
4617 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004618}
4619
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004620#elif defined(PYCC_GCC)
4621
4622/* standard posix version of popen() support */
4623static PyObject *
4624posix_popen(PyObject *self, PyObject *args)
4625{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004626 char *name;
4627 char *mode = "r";
4628 int bufsize = -1;
4629 FILE *fp;
4630 PyObject *f;
4631 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4632 return NULL;
4633 Py_BEGIN_ALLOW_THREADS
4634 fp = popen(name, mode);
4635 Py_END_ALLOW_THREADS
4636 if (fp == NULL)
4637 return posix_error();
4638 f = PyFile_FromFile(fp, name, mode, pclose);
4639 if (f != NULL)
4640 PyFile_SetBufSize(f, bufsize);
4641 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004642}
4643
4644/* fork() under OS/2 has lots'o'warts
4645 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4646 * most of this code is a ripoff of the win32 code, but using the
4647 * capabilities of EMX's C library routines
4648 */
4649
4650/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4651#define POPEN_1 1
4652#define POPEN_2 2
4653#define POPEN_3 3
4654#define POPEN_4 4
4655
4656static PyObject *_PyPopen(char *, int, int, int);
4657static int _PyPclose(FILE *file);
4658
4659/*
4660 * Internal dictionary mapping popen* file pointers to process handles,
4661 * for use when retrieving the process exit code. See _PyPclose() below
4662 * for more information on this dictionary's use.
4663 */
4664static PyObject *_PyPopenProcs = NULL;
4665
4666/* os2emx version of popen2()
4667 *
4668 * The result of this function is a pipe (file) connected to the
4669 * process's stdin, and a pipe connected to the process's stdout.
4670 */
4671
4672static PyObject *
4673os2emx_popen2(PyObject *self, PyObject *args)
4674{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004675 PyObject *f;
4676 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004677
Victor Stinnerd6f85422010-05-05 23:33:33 +00004678 char *cmdstring;
4679 char *mode = "t";
4680 int bufsize = -1;
4681 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4682 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004683
Victor Stinnerd6f85422010-05-05 23:33:33 +00004684 if (*mode == 't')
4685 tm = O_TEXT;
4686 else if (*mode != 'b') {
4687 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4688 return NULL;
4689 } else
4690 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004691
Victor Stinnerd6f85422010-05-05 23:33:33 +00004692 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004693
Victor Stinnerd6f85422010-05-05 23:33:33 +00004694 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004695}
4696
4697/*
4698 * Variation on os2emx.popen2
4699 *
4700 * The result of this function is 3 pipes - the process's stdin,
4701 * stdout and stderr
4702 */
4703
4704static PyObject *
4705os2emx_popen3(PyObject *self, PyObject *args)
4706{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004707 PyObject *f;
4708 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004709
Victor Stinnerd6f85422010-05-05 23:33:33 +00004710 char *cmdstring;
4711 char *mode = "t";
4712 int bufsize = -1;
4713 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4714 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004715
Victor Stinnerd6f85422010-05-05 23:33:33 +00004716 if (*mode == 't')
4717 tm = O_TEXT;
4718 else if (*mode != 'b') {
4719 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4720 return NULL;
4721 } else
4722 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004723
Victor Stinnerd6f85422010-05-05 23:33:33 +00004724 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004725
Victor Stinnerd6f85422010-05-05 23:33:33 +00004726 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004727}
4728
4729/*
4730 * Variation on os2emx.popen2
4731 *
Tim Peters11b23062003-04-23 02:39:17 +00004732 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004733 * and stdout+stderr combined as a single pipe.
4734 */
4735
4736static PyObject *
4737os2emx_popen4(PyObject *self, PyObject *args)
4738{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004739 PyObject *f;
4740 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004741
Victor Stinnerd6f85422010-05-05 23:33:33 +00004742 char *cmdstring;
4743 char *mode = "t";
4744 int bufsize = -1;
4745 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4746 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004747
Victor Stinnerd6f85422010-05-05 23:33:33 +00004748 if (*mode == 't')
4749 tm = O_TEXT;
4750 else if (*mode != 'b') {
4751 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4752 return NULL;
4753 } else
4754 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004755
Victor Stinnerd6f85422010-05-05 23:33:33 +00004756 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004757
Victor Stinnerd6f85422010-05-05 23:33:33 +00004758 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004759}
4760
4761/* a couple of structures for convenient handling of multiple
4762 * file handles and pipes
4763 */
4764struct file_ref
4765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004766 int handle;
4767 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004768};
4769
4770struct pipe_ref
4771{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004772 int rd;
4773 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004774};
4775
4776/* The following code is derived from the win32 code */
4777
4778static PyObject *
4779_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4780{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004781 struct file_ref stdio[3];
4782 struct pipe_ref p_fd[3];
4783 FILE *p_s[3];
4784 int file_count, i, pipe_err;
4785 pid_t pipe_pid;
4786 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4787 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004788
Victor Stinnerd6f85422010-05-05 23:33:33 +00004789 /* file modes for subsequent fdopen's on pipe handles */
4790 if (mode == O_TEXT)
4791 {
4792 rd_mode = "rt";
4793 wr_mode = "wt";
4794 }
4795 else
4796 {
4797 rd_mode = "rb";
4798 wr_mode = "wb";
4799 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004800
Victor Stinnerd6f85422010-05-05 23:33:33 +00004801 /* prepare shell references */
4802 if ((shell = getenv("EMXSHELL")) == NULL)
4803 if ((shell = getenv("COMSPEC")) == NULL)
4804 {
4805 errno = ENOENT;
4806 return posix_error();
4807 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004808
Victor Stinnerd6f85422010-05-05 23:33:33 +00004809 sh_name = _getname(shell);
4810 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4811 opt = "/c";
4812 else
4813 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004814
Victor Stinnerd6f85422010-05-05 23:33:33 +00004815 /* save current stdio fds + their flags, and set not inheritable */
4816 i = pipe_err = 0;
4817 while (pipe_err >= 0 && i < 3)
4818 {
4819 pipe_err = stdio[i].handle = dup(i);
4820 stdio[i].flags = fcntl(i, F_GETFD, 0);
4821 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4822 i++;
4823 }
4824 if (pipe_err < 0)
4825 {
4826 /* didn't get them all saved - clean up and bail out */
4827 int saved_err = errno;
4828 while (i-- > 0)
4829 {
4830 close(stdio[i].handle);
4831 }
4832 errno = saved_err;
4833 return posix_error();
4834 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004835
Victor Stinnerd6f85422010-05-05 23:33:33 +00004836 /* create pipe ends */
4837 file_count = 2;
4838 if (n == POPEN_3)
4839 file_count = 3;
4840 i = pipe_err = 0;
4841 while ((pipe_err == 0) && (i < file_count))
4842 pipe_err = pipe((int *)&p_fd[i++]);
4843 if (pipe_err < 0)
4844 {
4845 /* didn't get them all made - clean up and bail out */
4846 while (i-- > 0)
4847 {
4848 close(p_fd[i].wr);
4849 close(p_fd[i].rd);
4850 }
4851 errno = EPIPE;
4852 return posix_error();
4853 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004854
Victor Stinnerd6f85422010-05-05 23:33:33 +00004855 /* change the actual standard IO streams over temporarily,
4856 * making the retained pipe ends non-inheritable
4857 */
4858 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004859
Victor Stinnerd6f85422010-05-05 23:33:33 +00004860 /* - stdin */
4861 if (dup2(p_fd[0].rd, 0) == 0)
4862 {
4863 close(p_fd[0].rd);
4864 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4865 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4866 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4867 {
4868 close(p_fd[0].wr);
4869 pipe_err = -1;
4870 }
4871 }
4872 else
4873 {
4874 pipe_err = -1;
4875 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004876
Victor Stinnerd6f85422010-05-05 23:33:33 +00004877 /* - stdout */
4878 if (pipe_err == 0)
4879 {
4880 if (dup2(p_fd[1].wr, 1) == 1)
4881 {
4882 close(p_fd[1].wr);
4883 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4884 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4885 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4886 {
4887 close(p_fd[1].rd);
4888 pipe_err = -1;
4889 }
4890 }
4891 else
4892 {
4893 pipe_err = -1;
4894 }
4895 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004896
Victor Stinnerd6f85422010-05-05 23:33:33 +00004897 /* - stderr, as required */
4898 if (pipe_err == 0)
4899 switch (n)
4900 {
4901 case POPEN_3:
4902 {
4903 if (dup2(p_fd[2].wr, 2) == 2)
4904 {
4905 close(p_fd[2].wr);
4906 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4907 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4908 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4909 {
4910 close(p_fd[2].rd);
4911 pipe_err = -1;
4912 }
4913 }
4914 else
4915 {
4916 pipe_err = -1;
4917 }
4918 break;
4919 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004920
Victor Stinnerd6f85422010-05-05 23:33:33 +00004921 case POPEN_4:
4922 {
4923 if (dup2(1, 2) != 2)
4924 {
4925 pipe_err = -1;
4926 }
4927 break;
4928 }
4929 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004930
Victor Stinnerd6f85422010-05-05 23:33:33 +00004931 /* spawn the child process */
4932 if (pipe_err == 0)
4933 {
4934 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4935 if (pipe_pid == -1)
4936 {
4937 pipe_err = -1;
4938 }
4939 else
4940 {
4941 /* save the PID into the FILE structure
4942 * NOTE: this implementation doesn't actually
4943 * take advantage of this, but do it for
4944 * completeness - AIM Apr01
4945 */
4946 for (i = 0; i < file_count; i++)
4947 p_s[i]->_pid = pipe_pid;
4948 }
4949 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004950
Victor Stinnerd6f85422010-05-05 23:33:33 +00004951 /* reset standard IO to normal */
4952 for (i = 0; i < 3; i++)
4953 {
4954 dup2(stdio[i].handle, i);
4955 fcntl(i, F_SETFD, stdio[i].flags);
4956 close(stdio[i].handle);
4957 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004958
Victor Stinnerd6f85422010-05-05 23:33:33 +00004959 /* if any remnant problems, clean up and bail out */
4960 if (pipe_err < 0)
4961 {
4962 for (i = 0; i < 3; i++)
4963 {
4964 close(p_fd[i].rd);
4965 close(p_fd[i].wr);
4966 }
4967 errno = EPIPE;
4968 return posix_error_with_filename(cmdstring);
4969 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004970
Victor Stinnerd6f85422010-05-05 23:33:33 +00004971 /* build tuple of file objects to return */
4972 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4973 PyFile_SetBufSize(p_f[0], bufsize);
4974 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4975 PyFile_SetBufSize(p_f[1], bufsize);
4976 if (n == POPEN_3)
4977 {
4978 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4979 PyFile_SetBufSize(p_f[0], bufsize);
4980 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4981 }
4982 else
4983 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004984
Victor Stinnerd6f85422010-05-05 23:33:33 +00004985 /*
4986 * Insert the files we've created into the process dictionary
4987 * all referencing the list with the process handle and the
4988 * initial number of files (see description below in _PyPclose).
4989 * Since if _PyPclose later tried to wait on a process when all
4990 * handles weren't closed, it could create a deadlock with the
4991 * child, we spend some energy here to try to ensure that we
4992 * either insert all file handles into the dictionary or none
4993 * at all. It's a little clumsy with the various popen modes
4994 * and variable number of files involved.
4995 */
4996 if (!_PyPopenProcs)
4997 {
4998 _PyPopenProcs = PyDict_New();
4999 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005000
Victor Stinnerd6f85422010-05-05 23:33:33 +00005001 if (_PyPopenProcs)
5002 {
5003 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
5004 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005005
Victor Stinnerd6f85422010-05-05 23:33:33 +00005006 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5007 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005008
Victor Stinnerd6f85422010-05-05 23:33:33 +00005009 procObj = PyList_New(2);
5010 pidObj = PyLong_FromPid(pipe_pid);
5011 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005012
Victor Stinnerd6f85422010-05-05 23:33:33 +00005013 if (procObj && pidObj && intObj)
5014 {
5015 PyList_SetItem(procObj, 0, pidObj);
5016 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005017
Victor Stinnerd6f85422010-05-05 23:33:33 +00005018 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
5019 if (fileObj[0])
5020 {
5021 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5022 fileObj[0],
5023 procObj);
5024 }
5025 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5026 if (fileObj[1])
5027 {
5028 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5029 fileObj[1],
5030 procObj);
5031 }
5032 if (file_count >= 3)
5033 {
5034 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5035 if (fileObj[2])
5036 {
5037 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5038 fileObj[2],
5039 procObj);
5040 }
5041 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005042
Victor Stinnerd6f85422010-05-05 23:33:33 +00005043 if (ins_rc[0] < 0 || !fileObj[0] ||
5044 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5045 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5046 {
5047 /* Something failed - remove any dictionary
5048 * entries that did make it.
5049 */
5050 if (!ins_rc[0] && fileObj[0])
5051 {
5052 PyDict_DelItem(_PyPopenProcs,
5053 fileObj[0]);
5054 }
5055 if (!ins_rc[1] && fileObj[1])
5056 {
5057 PyDict_DelItem(_PyPopenProcs,
5058 fileObj[1]);
5059 }
5060 if (!ins_rc[2] && fileObj[2])
5061 {
5062 PyDict_DelItem(_PyPopenProcs,
5063 fileObj[2]);
5064 }
5065 }
5066 }
Tim Peters11b23062003-04-23 02:39:17 +00005067
Victor Stinnerd6f85422010-05-05 23:33:33 +00005068 /*
5069 * Clean up our localized references for the dictionary keys
5070 * and value since PyDict_SetItem will Py_INCREF any copies
5071 * that got placed in the dictionary.
5072 */
5073 Py_XDECREF(procObj);
5074 Py_XDECREF(fileObj[0]);
5075 Py_XDECREF(fileObj[1]);
5076 Py_XDECREF(fileObj[2]);
5077 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005078
Victor Stinnerd6f85422010-05-05 23:33:33 +00005079 /* Child is launched. */
5080 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005081}
5082
5083/*
5084 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5085 * exit code for the child process and return as a result of the close.
5086 *
5087 * This function uses the _PyPopenProcs dictionary in order to map the
5088 * input file pointer to information about the process that was
5089 * originally created by the popen* call that created the file pointer.
5090 * The dictionary uses the file pointer as a key (with one entry
5091 * inserted for each file returned by the original popen* call) and a
5092 * single list object as the value for all files from a single call.
5093 * The list object contains the Win32 process handle at [0], and a file
5094 * count at [1], which is initialized to the total number of file
5095 * handles using that list.
5096 *
5097 * This function closes whichever handle it is passed, and decrements
5098 * the file count in the dictionary for the process handle pointed to
5099 * by this file. On the last close (when the file count reaches zero),
5100 * this function will wait for the child process and then return its
5101 * exit code as the result of the close() operation. This permits the
5102 * files to be closed in any order - it is always the close() of the
5103 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005104 *
5105 * NOTE: This function is currently called with the GIL released.
5106 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005107 */
5108
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005109static int _PyPclose(FILE *file)
5110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005111 int result;
5112 int exit_code;
5113 pid_t pipe_pid;
5114 PyObject *procObj, *pidObj, *intObj, *fileObj;
5115 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005116#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005117 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005118#endif
5119
Victor Stinnerd6f85422010-05-05 23:33:33 +00005120 /* Close the file handle first, to ensure it can't block the
5121 * child from exiting if it's the last handle.
5122 */
5123 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005124
5125#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005126 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005127#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005128 if (_PyPopenProcs)
5129 {
5130 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5131 (procObj = PyDict_GetItem(_PyPopenProcs,
5132 fileObj)) != NULL &&
5133 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5134 (intObj = PyList_GetItem(procObj,1)) != NULL)
5135 {
5136 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5137 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005138
Victor Stinnerd6f85422010-05-05 23:33:33 +00005139 if (file_count > 1)
5140 {
5141 /* Still other files referencing process */
5142 file_count--;
5143 PyList_SetItem(procObj,1,
5144 PyInt_FromLong((long) file_count));
5145 }
5146 else
5147 {
5148 /* Last file for this process */
5149 if (result != EOF &&
5150 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5151 {
5152 /* extract exit status */
5153 if (WIFEXITED(exit_code))
5154 {
5155 result = WEXITSTATUS(exit_code);
5156 }
5157 else
5158 {
5159 errno = EPIPE;
5160 result = -1;
5161 }
5162 }
5163 else
5164 {
5165 /* Indicate failure - this will cause the file object
5166 * to raise an I/O error and translate the last
5167 * error code from errno. We do have a problem with
5168 * last errors that overlap the normal errno table,
5169 * but that's a consistent problem with the file object.
5170 */
5171 result = -1;
5172 }
5173 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005174
Victor Stinnerd6f85422010-05-05 23:33:33 +00005175 /* Remove this file pointer from dictionary */
5176 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005177
Victor Stinnerd6f85422010-05-05 23:33:33 +00005178 if (PyDict_Size(_PyPopenProcs) == 0)
5179 {
5180 Py_DECREF(_PyPopenProcs);
5181 _PyPopenProcs = NULL;
5182 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005183
Victor Stinnerd6f85422010-05-05 23:33:33 +00005184 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005185
Victor Stinnerd6f85422010-05-05 23:33:33 +00005186 Py_XDECREF(fileObj);
5187 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005188
5189#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005190 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005191#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005192 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005193}
5194
5195#endif /* PYCC_??? */
5196
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005197#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005198
5199/*
5200 * Portable 'popen' replacement for Win32.
5201 *
5202 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5203 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005204 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005205 */
5206
5207#include <malloc.h>
5208#include <io.h>
5209#include <fcntl.h>
5210
5211/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5212#define POPEN_1 1
5213#define POPEN_2 2
5214#define POPEN_3 3
5215#define POPEN_4 4
5216
5217static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005218static int _PyPclose(FILE *file);
5219
5220/*
5221 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005222 * for use when retrieving the process exit code. See _PyPclose() below
5223 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005224 */
5225static PyObject *_PyPopenProcs = NULL;
5226
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005227
5228/* popen that works from a GUI.
5229 *
5230 * The result of this function is a pipe (file) connected to the
5231 * processes stdin or stdout, depending on the requested mode.
5232 */
5233
5234static PyObject *
5235posix_popen(PyObject *self, PyObject *args)
5236{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005237 PyObject *f;
5238 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005239
Victor Stinnerd6f85422010-05-05 23:33:33 +00005240 char *cmdstring;
5241 char *mode = "r";
5242 int bufsize = -1;
5243 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5244 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005245
Victor Stinnerd6f85422010-05-05 23:33:33 +00005246 if (*mode == 'r')
5247 tm = _O_RDONLY;
5248 else if (*mode != 'w') {
5249 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5250 return NULL;
5251 } else
5252 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005253
Victor Stinnerd6f85422010-05-05 23:33:33 +00005254 if (bufsize != -1) {
5255 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5256 return NULL;
5257 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005258
Victor Stinnerd6f85422010-05-05 23:33:33 +00005259 if (*(mode+1) == 't')
5260 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5261 else if (*(mode+1) == 'b')
5262 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5263 else
5264 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005265
Victor Stinnerd6f85422010-05-05 23:33:33 +00005266 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005267}
5268
5269/* Variation on win32pipe.popen
5270 *
5271 * The result of this function is a pipe (file) connected to the
5272 * process's stdin, and a pipe connected to the process's stdout.
5273 */
5274
5275static PyObject *
5276win32_popen2(PyObject *self, PyObject *args)
5277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005278 PyObject *f;
5279 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005280
Victor Stinnerd6f85422010-05-05 23:33:33 +00005281 char *cmdstring;
5282 char *mode = "t";
5283 int bufsize = -1;
5284 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5285 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005286
Victor Stinnerd6f85422010-05-05 23:33:33 +00005287 if (*mode == 't')
5288 tm = _O_TEXT;
5289 else if (*mode != 'b') {
5290 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5291 return NULL;
5292 } else
5293 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005294
Victor Stinnerd6f85422010-05-05 23:33:33 +00005295 if (bufsize != -1) {
5296 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5297 return NULL;
5298 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005299
Victor Stinnerd6f85422010-05-05 23:33:33 +00005300 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005301
Victor Stinnerd6f85422010-05-05 23:33:33 +00005302 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005303}
5304
5305/*
5306 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005307 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005308 * The result of this function is 3 pipes - the process's stdin,
5309 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005310 */
5311
5312static PyObject *
5313win32_popen3(PyObject *self, PyObject *args)
5314{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005315 PyObject *f;
5316 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005317
Victor Stinnerd6f85422010-05-05 23:33:33 +00005318 char *cmdstring;
5319 char *mode = "t";
5320 int bufsize = -1;
5321 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5322 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005323
Victor Stinnerd6f85422010-05-05 23:33:33 +00005324 if (*mode == 't')
5325 tm = _O_TEXT;
5326 else if (*mode != 'b') {
5327 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5328 return NULL;
5329 } else
5330 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005331
Victor Stinnerd6f85422010-05-05 23:33:33 +00005332 if (bufsize != -1) {
5333 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5334 return NULL;
5335 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005336
Victor Stinnerd6f85422010-05-05 23:33:33 +00005337 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005338
Victor Stinnerd6f85422010-05-05 23:33:33 +00005339 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005340}
5341
5342/*
5343 * Variation on win32pipe.popen
5344 *
Tim Peters5aa91602002-01-30 05:46:57 +00005345 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005346 * and stdout+stderr combined as a single pipe.
5347 */
5348
5349static PyObject *
5350win32_popen4(PyObject *self, PyObject *args)
5351{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005352 PyObject *f;
5353 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005354
Victor Stinnerd6f85422010-05-05 23:33:33 +00005355 char *cmdstring;
5356 char *mode = "t";
5357 int bufsize = -1;
5358 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5359 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005360
Victor Stinnerd6f85422010-05-05 23:33:33 +00005361 if (*mode == 't')
5362 tm = _O_TEXT;
5363 else if (*mode != 'b') {
5364 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5365 return NULL;
5366 } else
5367 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005368
Victor Stinnerd6f85422010-05-05 23:33:33 +00005369 if (bufsize != -1) {
5370 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5371 return NULL;
5372 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005373
Victor Stinnerd6f85422010-05-05 23:33:33 +00005374 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005375
Victor Stinnerd6f85422010-05-05 23:33:33 +00005376 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005377}
5378
Mark Hammond08501372001-01-31 07:30:29 +00005379static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005380_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005381 HANDLE hStdin,
5382 HANDLE hStdout,
5383 HANDLE hStderr,
5384 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005385{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005386 PROCESS_INFORMATION piProcInfo;
5387 STARTUPINFO siStartInfo;
5388 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5389 char *s1,*s2, *s3 = " /c ";
5390 const char *szConsoleSpawn = "w9xpopen.exe";
5391 int i;
5392 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005393
Victor Stinnerd6f85422010-05-05 23:33:33 +00005394 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5395 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005396
Victor Stinnerd6f85422010-05-05 23:33:33 +00005397 s1 = (char *)alloca(i);
5398 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5399 /* x < i, so x fits into an integer */
5400 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005401
Victor Stinnerd6f85422010-05-05 23:33:33 +00005402 /* Explicitly check if we are using COMMAND.COM. If we are
5403 * then use the w9xpopen hack.
5404 */
5405 comshell = s1 + x;
5406 while (comshell >= s1 && *comshell != '\\')
5407 --comshell;
5408 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005409
Victor Stinnerd6f85422010-05-05 23:33:33 +00005410 if (GetVersion() < 0x80000000 &&
5411 _stricmp(comshell, "command.com") != 0) {
5412 /* NT/2000 and not using command.com. */
5413 x = i + strlen(s3) + strlen(cmdstring) + 1;
5414 s2 = (char *)alloca(x);
5415 ZeroMemory(s2, x);
5416 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5417 }
5418 else {
5419 /*
5420 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5421 * the workaround listed in KB: Q150956
5422 */
5423 char modulepath[_MAX_PATH];
5424 struct stat statinfo;
5425 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5426 for (x = i = 0; modulepath[i]; i++)
5427 if (modulepath[i] == SEP)
5428 x = i+1;
5429 modulepath[x] = '\0';
5430 /* Create the full-name to w9xpopen, so we can test it exists */
5431 strncat(modulepath,
5432 szConsoleSpawn,
5433 (sizeof(modulepath)/sizeof(modulepath[0]))
5434 -strlen(modulepath));
5435 if (stat(modulepath, &statinfo) != 0) {
5436 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5437 /* Eeek - file-not-found - possibly an embedding
5438 situation - see if we can locate it in sys.prefix
5439 */
5440 strncpy(modulepath,
5441 Py_GetExecPrefix(),
5442 mplen);
5443 modulepath[mplen-1] = '\0';
5444 if (modulepath[strlen(modulepath)-1] != '\\')
5445 strcat(modulepath, "\\");
5446 strncat(modulepath,
5447 szConsoleSpawn,
5448 mplen-strlen(modulepath));
5449 /* No where else to look - raise an easily identifiable
5450 error, rather than leaving Windows to report
5451 "file not found" - as the user is probably blissfully
5452 unaware this shim EXE is used, and it will confuse them.
5453 (well, it confused me for a while ;-)
5454 */
5455 if (stat(modulepath, &statinfo) != 0) {
5456 PyErr_Format(PyExc_RuntimeError,
5457 "Can not locate '%s' which is needed "
5458 "for popen to work with your shell "
5459 "or platform.",
5460 szConsoleSpawn);
5461 return FALSE;
5462 }
5463 }
5464 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5465 strlen(modulepath) +
5466 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005467
Victor Stinnerd6f85422010-05-05 23:33:33 +00005468 s2 = (char *)alloca(x);
5469 ZeroMemory(s2, x);
5470 /* To maintain correct argument passing semantics,
5471 we pass the command-line as it stands, and allow
5472 quoting to be applied. w9xpopen.exe will then
5473 use its argv vector, and re-quote the necessary
5474 args for the ultimate child process.
5475 */
5476 PyOS_snprintf(
5477 s2, x,
5478 "\"%s\" %s%s%s",
5479 modulepath,
5480 s1,
5481 s3,
5482 cmdstring);
5483 /* Not passing CREATE_NEW_CONSOLE has been known to
5484 cause random failures on win9x. Specifically a
5485 dialog:
5486 "Your program accessed mem currently in use at xxx"
5487 and a hopeful warning about the stability of your
5488 system.
5489 Cost is Ctrl+C won't kill children, but anyone
5490 who cares can have a go!
5491 */
5492 dwProcessFlags |= CREATE_NEW_CONSOLE;
5493 }
5494 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005495
Victor Stinnerd6f85422010-05-05 23:33:33 +00005496 /* Could be an else here to try cmd.exe / command.com in the path
5497 Now we'll just error out.. */
5498 else {
5499 PyErr_SetString(PyExc_RuntimeError,
5500 "Cannot locate a COMSPEC environment variable to "
5501 "use as the shell");
5502 return FALSE;
5503 }
Tim Peters5aa91602002-01-30 05:46:57 +00005504
Victor Stinnerd6f85422010-05-05 23:33:33 +00005505 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5506 siStartInfo.cb = sizeof(STARTUPINFO);
5507 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5508 siStartInfo.hStdInput = hStdin;
5509 siStartInfo.hStdOutput = hStdout;
5510 siStartInfo.hStdError = hStderr;
5511 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005512
Victor Stinnerd6f85422010-05-05 23:33:33 +00005513 if (CreateProcess(NULL,
5514 s2,
5515 NULL,
5516 NULL,
5517 TRUE,
5518 dwProcessFlags,
5519 NULL,
5520 NULL,
5521 &siStartInfo,
5522 &piProcInfo) ) {
5523 /* Close the handles now so anyone waiting is woken. */
5524 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005525
Victor Stinnerd6f85422010-05-05 23:33:33 +00005526 /* Return process handle */
5527 *hProcess = piProcInfo.hProcess;
5528 return TRUE;
5529 }
5530 win32_error("CreateProcess", s2);
5531 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005532}
5533
5534/* The following code is based off of KB: Q190351 */
5535
5536static PyObject *
5537_PyPopen(char *cmdstring, int mode, int n)
5538{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005539 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5540 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5541 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005542
Victor Stinnerd6f85422010-05-05 23:33:33 +00005543 SECURITY_ATTRIBUTES saAttr;
5544 BOOL fSuccess;
5545 int fd1, fd2, fd3;
5546 FILE *f1, *f2, *f3;
5547 long file_count;
5548 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005549
Victor Stinnerd6f85422010-05-05 23:33:33 +00005550 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5551 saAttr.bInheritHandle = TRUE;
5552 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005553
Victor Stinnerd6f85422010-05-05 23:33:33 +00005554 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5555 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005556
Victor Stinnerd6f85422010-05-05 23:33:33 +00005557 /* Create new output read handle and the input write handle. Set
5558 * the inheritance properties to FALSE. Otherwise, the child inherits
5559 * these handles; resulting in non-closeable handles to the pipes
5560 * being created. */
5561 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5562 GetCurrentProcess(), &hChildStdinWrDup, 0,
5563 FALSE,
5564 DUPLICATE_SAME_ACCESS);
5565 if (!fSuccess)
5566 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005567
Victor Stinnerd6f85422010-05-05 23:33:33 +00005568 /* Close the inheritable version of ChildStdin
5569 that we're using. */
5570 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005571
Victor Stinnerd6f85422010-05-05 23:33:33 +00005572 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5573 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005574
Victor Stinnerd6f85422010-05-05 23:33:33 +00005575 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5576 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5577 FALSE, DUPLICATE_SAME_ACCESS);
5578 if (!fSuccess)
5579 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005580
Victor Stinnerd6f85422010-05-05 23:33:33 +00005581 /* Close the inheritable version of ChildStdout
5582 that we're using. */
5583 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005584
Victor Stinnerd6f85422010-05-05 23:33:33 +00005585 if (n != POPEN_4) {
5586 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5587 return win32_error("CreatePipe", NULL);
5588 fSuccess = DuplicateHandle(GetCurrentProcess(),
5589 hChildStderrRd,
5590 GetCurrentProcess(),
5591 &hChildStderrRdDup, 0,
5592 FALSE, DUPLICATE_SAME_ACCESS);
5593 if (!fSuccess)
5594 return win32_error("DuplicateHandle", NULL);
5595 /* Close the inheritable version of ChildStdErr that we're using. */
5596 CloseHandle(hChildStderrRd);
5597 }
Tim Peters5aa91602002-01-30 05:46:57 +00005598
Victor Stinnerd6f85422010-05-05 23:33:33 +00005599 switch (n) {
5600 case POPEN_1:
5601 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5602 case _O_WRONLY | _O_TEXT:
5603 /* Case for writing to child Stdin in text mode. */
5604 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5605 f1 = _fdopen(fd1, "w");
5606 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5607 PyFile_SetBufSize(f, 0);
5608 /* We don't care about these pipes anymore, so close them. */
5609 CloseHandle(hChildStdoutRdDup);
5610 CloseHandle(hChildStderrRdDup);
5611 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005612
Victor Stinnerd6f85422010-05-05 23:33:33 +00005613 case _O_RDONLY | _O_TEXT:
5614 /* Case for reading from child Stdout in text mode. */
5615 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5616 f1 = _fdopen(fd1, "r");
5617 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5618 PyFile_SetBufSize(f, 0);
5619 /* We don't care about these pipes anymore, so close them. */
5620 CloseHandle(hChildStdinWrDup);
5621 CloseHandle(hChildStderrRdDup);
5622 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005623
Victor Stinnerd6f85422010-05-05 23:33:33 +00005624 case _O_RDONLY | _O_BINARY:
5625 /* Case for readinig from child Stdout in binary mode. */
5626 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5627 f1 = _fdopen(fd1, "rb");
5628 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5629 PyFile_SetBufSize(f, 0);
5630 /* We don't care about these pipes anymore, so close them. */
5631 CloseHandle(hChildStdinWrDup);
5632 CloseHandle(hChildStderrRdDup);
5633 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005634
Victor Stinnerd6f85422010-05-05 23:33:33 +00005635 case _O_WRONLY | _O_BINARY:
5636 /* Case for writing to child Stdin in binary mode. */
5637 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5638 f1 = _fdopen(fd1, "wb");
5639 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5640 PyFile_SetBufSize(f, 0);
5641 /* We don't care about these pipes anymore, so close them. */
5642 CloseHandle(hChildStdoutRdDup);
5643 CloseHandle(hChildStderrRdDup);
5644 break;
5645 }
5646 file_count = 1;
5647 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005648
Victor Stinnerd6f85422010-05-05 23:33:33 +00005649 case POPEN_2:
5650 case POPEN_4:
5651 {
5652 char *m1, *m2;
5653 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005654
Victor Stinnerd6f85422010-05-05 23:33:33 +00005655 if (mode & _O_TEXT) {
5656 m1 = "r";
5657 m2 = "w";
5658 } else {
5659 m1 = "rb";
5660 m2 = "wb";
5661 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005662
Victor Stinnerd6f85422010-05-05 23:33:33 +00005663 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5664 f1 = _fdopen(fd1, m2);
5665 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5666 f2 = _fdopen(fd2, m1);
5667 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5668 PyFile_SetBufSize(p1, 0);
5669 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5670 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005671
Victor Stinnerd6f85422010-05-05 23:33:33 +00005672 if (n != 4)
5673 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005674
Victor Stinnerd6f85422010-05-05 23:33:33 +00005675 f = PyTuple_Pack(2,p1,p2);
5676 Py_XDECREF(p1);
5677 Py_XDECREF(p2);
5678 file_count = 2;
5679 break;
5680 }
Tim Peters5aa91602002-01-30 05:46:57 +00005681
Victor Stinnerd6f85422010-05-05 23:33:33 +00005682 case POPEN_3:
5683 {
5684 char *m1, *m2;
5685 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005686
Victor Stinnerd6f85422010-05-05 23:33:33 +00005687 if (mode & _O_TEXT) {
5688 m1 = "r";
5689 m2 = "w";
5690 } else {
5691 m1 = "rb";
5692 m2 = "wb";
5693 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005694
Victor Stinnerd6f85422010-05-05 23:33:33 +00005695 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5696 f1 = _fdopen(fd1, m2);
5697 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5698 f2 = _fdopen(fd2, m1);
5699 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5700 f3 = _fdopen(fd3, m1);
5701 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5702 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5703 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5704 PyFile_SetBufSize(p1, 0);
5705 PyFile_SetBufSize(p2, 0);
5706 PyFile_SetBufSize(p3, 0);
5707 f = PyTuple_Pack(3,p1,p2,p3);
5708 Py_XDECREF(p1);
5709 Py_XDECREF(p2);
5710 Py_XDECREF(p3);
5711 file_count = 3;
5712 break;
5713 }
5714 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005715
Victor Stinnerd6f85422010-05-05 23:33:33 +00005716 if (n == POPEN_4) {
5717 if (!_PyPopenCreateProcess(cmdstring,
5718 hChildStdinRd,
5719 hChildStdoutWr,
5720 hChildStdoutWr,
5721 &hProcess))
5722 return NULL;
5723 }
5724 else {
5725 if (!_PyPopenCreateProcess(cmdstring,
5726 hChildStdinRd,
5727 hChildStdoutWr,
5728 hChildStderrWr,
5729 &hProcess))
5730 return NULL;
5731 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005732
Victor Stinnerd6f85422010-05-05 23:33:33 +00005733 /*
5734 * Insert the files we've created into the process dictionary
5735 * all referencing the list with the process handle and the
5736 * initial number of files (see description below in _PyPclose).
5737 * Since if _PyPclose later tried to wait on a process when all
5738 * handles weren't closed, it could create a deadlock with the
5739 * child, we spend some energy here to try to ensure that we
5740 * either insert all file handles into the dictionary or none
5741 * at all. It's a little clumsy with the various popen modes
5742 * and variable number of files involved.
5743 */
5744 if (!_PyPopenProcs) {
5745 _PyPopenProcs = PyDict_New();
5746 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005747
Victor Stinnerd6f85422010-05-05 23:33:33 +00005748 if (_PyPopenProcs) {
5749 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5750 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005751
Victor Stinnerd6f85422010-05-05 23:33:33 +00005752 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5753 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005754
Victor Stinnerd6f85422010-05-05 23:33:33 +00005755 procObj = PyList_New(2);
5756 hProcessObj = PyLong_FromVoidPtr(hProcess);
5757 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005758
Victor Stinnerd6f85422010-05-05 23:33:33 +00005759 if (procObj && hProcessObj && intObj) {
5760 PyList_SetItem(procObj,0,hProcessObj);
5761 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005762
Victor Stinnerd6f85422010-05-05 23:33:33 +00005763 fileObj[0] = PyLong_FromVoidPtr(f1);
5764 if (fileObj[0]) {
5765 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5766 fileObj[0],
5767 procObj);
5768 }
5769 if (file_count >= 2) {
5770 fileObj[1] = PyLong_FromVoidPtr(f2);
5771 if (fileObj[1]) {
5772 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5773 fileObj[1],
5774 procObj);
5775 }
5776 }
5777 if (file_count >= 3) {
5778 fileObj[2] = PyLong_FromVoidPtr(f3);
5779 if (fileObj[2]) {
5780 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5781 fileObj[2],
5782 procObj);
5783 }
5784 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005785
Victor Stinnerd6f85422010-05-05 23:33:33 +00005786 if (ins_rc[0] < 0 || !fileObj[0] ||
5787 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5788 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5789 /* Something failed - remove any dictionary
5790 * entries that did make it.
5791 */
5792 if (!ins_rc[0] && fileObj[0]) {
5793 PyDict_DelItem(_PyPopenProcs,
5794 fileObj[0]);
5795 }
5796 if (!ins_rc[1] && fileObj[1]) {
5797 PyDict_DelItem(_PyPopenProcs,
5798 fileObj[1]);
5799 }
5800 if (!ins_rc[2] && fileObj[2]) {
5801 PyDict_DelItem(_PyPopenProcs,
5802 fileObj[2]);
5803 }
5804 }
5805 }
Tim Peters5aa91602002-01-30 05:46:57 +00005806
Victor Stinnerd6f85422010-05-05 23:33:33 +00005807 /*
5808 * Clean up our localized references for the dictionary keys
5809 * and value since PyDict_SetItem will Py_INCREF any copies
5810 * that got placed in the dictionary.
5811 */
5812 Py_XDECREF(procObj);
5813 Py_XDECREF(fileObj[0]);
5814 Py_XDECREF(fileObj[1]);
5815 Py_XDECREF(fileObj[2]);
5816 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005817
Victor Stinnerd6f85422010-05-05 23:33:33 +00005818 /* Child is launched. Close the parents copy of those pipe
5819 * handles that only the child should have open. You need to
5820 * make sure that no handles to the write end of the output pipe
5821 * are maintained in this process or else the pipe will not close
5822 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005823
Victor Stinnerd6f85422010-05-05 23:33:33 +00005824 if (!CloseHandle(hChildStdinRd))
5825 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005826
Victor Stinnerd6f85422010-05-05 23:33:33 +00005827 if (!CloseHandle(hChildStdoutWr))
5828 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005829
Victor Stinnerd6f85422010-05-05 23:33:33 +00005830 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5831 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005832
Victor Stinnerd6f85422010-05-05 23:33:33 +00005833 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005834}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005835
5836/*
5837 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5838 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005839 *
5840 * This function uses the _PyPopenProcs dictionary in order to map the
5841 * input file pointer to information about the process that was
5842 * originally created by the popen* call that created the file pointer.
5843 * The dictionary uses the file pointer as a key (with one entry
5844 * inserted for each file returned by the original popen* call) and a
5845 * single list object as the value for all files from a single call.
5846 * The list object contains the Win32 process handle at [0], and a file
5847 * count at [1], which is initialized to the total number of file
5848 * handles using that list.
5849 *
5850 * This function closes whichever handle it is passed, and decrements
5851 * the file count in the dictionary for the process handle pointed to
5852 * by this file. On the last close (when the file count reaches zero),
5853 * this function will wait for the child process and then return its
5854 * exit code as the result of the close() operation. This permits the
5855 * files to be closed in any order - it is always the close() of the
5856 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005857 *
5858 * NOTE: This function is currently called with the GIL released.
5859 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005860 */
Tim Peters736aa322000-09-01 06:51:24 +00005861
Fredrik Lundh56055a42000-07-23 19:47:12 +00005862static int _PyPclose(FILE *file)
5863{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005864 int result;
5865 DWORD exit_code;
5866 HANDLE hProcess;
5867 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5868 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005869#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005870 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005871#endif
5872
Victor Stinnerd6f85422010-05-05 23:33:33 +00005873 /* Close the file handle first, to ensure it can't block the
5874 * child from exiting if it's the last handle.
5875 */
5876 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005877#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005878 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005879#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005880 if (_PyPopenProcs) {
5881 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5882 (procObj = PyDict_GetItem(_PyPopenProcs,
5883 fileObj)) != NULL &&
5884 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5885 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005886
Victor Stinnerd6f85422010-05-05 23:33:33 +00005887 hProcess = PyLong_AsVoidPtr(hProcessObj);
5888 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005889
Victor Stinnerd6f85422010-05-05 23:33:33 +00005890 if (file_count > 1) {
5891 /* Still other files referencing process */
5892 file_count--;
5893 PyList_SetItem(procObj,1,
5894 PyInt_FromLong(file_count));
5895 } else {
5896 /* Last file for this process */
5897 if (result != EOF &&
5898 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5899 GetExitCodeProcess(hProcess, &exit_code)) {
5900 /* Possible truncation here in 16-bit environments, but
5901 * real exit codes are just the lower byte in any event.
5902 */
5903 result = exit_code;
5904 } else {
5905 /* Indicate failure - this will cause the file object
5906 * to raise an I/O error and translate the last Win32
5907 * error code from errno. We do have a problem with
5908 * last errors that overlap the normal errno table,
5909 * but that's a consistent problem with the file object.
5910 */
5911 if (result != EOF) {
5912 /* If the error wasn't from the fclose(), then
5913 * set errno for the file object error handling.
5914 */
5915 errno = GetLastError();
5916 }
5917 result = -1;
5918 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005919
Victor Stinnerd6f85422010-05-05 23:33:33 +00005920 /* Free up the native handle at this point */
5921 CloseHandle(hProcess);
5922 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005923
Victor Stinnerd6f85422010-05-05 23:33:33 +00005924 /* Remove this file pointer from dictionary */
5925 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005926
Victor Stinnerd6f85422010-05-05 23:33:33 +00005927 if (PyDict_Size(_PyPopenProcs) == 0) {
5928 Py_DECREF(_PyPopenProcs);
5929 _PyPopenProcs = NULL;
5930 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005931
Victor Stinnerd6f85422010-05-05 23:33:33 +00005932 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005933
Victor Stinnerd6f85422010-05-05 23:33:33 +00005934 Py_XDECREF(fileObj);
5935 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005936
Tim Peters736aa322000-09-01 06:51:24 +00005937#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005938 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005939#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005940 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005941}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005942
5943#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005945posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005946{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005947 char *name;
5948 char *mode = "r";
5949 int bufsize = -1;
5950 FILE *fp;
5951 PyObject *f;
5952 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5953 return NULL;
5954 /* Strip mode of binary or text modifiers */
5955 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5956 mode = "r";
5957 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5958 mode = "w";
5959 Py_BEGIN_ALLOW_THREADS
5960 fp = popen(name, mode);
5961 Py_END_ALLOW_THREADS
5962 if (fp == NULL)
5963 return posix_error();
5964 f = PyFile_FromFile(fp, name, mode, pclose);
5965 if (f != NULL)
5966 PyFile_SetBufSize(f, bufsize);
5967 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005968}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005969
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005970#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005971#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005973
Guido van Rossumb6775db1994-08-01 11:34:53 +00005974#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005975PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005976"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977Set the current process's user id.");
5978
Barry Warsaw53699e91996-12-10 23:23:01 +00005979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005980posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005981{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005982 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005983 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005984 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005985 if (setuid(uid) < 0)
5986 return posix_error();
5987 Py_INCREF(Py_None);
5988 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005989}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005990#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005992
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005993#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005994PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005995"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005996Set the current process's effective user id.");
5997
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005998static PyObject *
5999posix_seteuid (PyObject *self, PyObject *args)
6000{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006001 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006002 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006003 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006004 if (seteuid(euid) < 0) {
6005 return posix_error();
6006 } else {
6007 Py_INCREF(Py_None);
6008 return Py_None;
6009 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006010}
6011#endif /* HAVE_SETEUID */
6012
6013#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006014PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006015"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006016Set the current process's effective group id.");
6017
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006018static PyObject *
6019posix_setegid (PyObject *self, PyObject *args)
6020{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006021 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006022 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006023 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006024 if (setegid(egid) < 0) {
6025 return posix_error();
6026 } else {
6027 Py_INCREF(Py_None);
6028 return Py_None;
6029 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006030}
6031#endif /* HAVE_SETEGID */
6032
6033#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006035"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036Set the current process's real and effective user ids.");
6037
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006038static PyObject *
6039posix_setreuid (PyObject *self, PyObject *args)
6040{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006041 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006042 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6043 _Py_Uid_Converter, &ruid,
6044 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006045 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006046 if (setreuid(ruid, euid) < 0) {
6047 return posix_error();
6048 } else {
6049 Py_INCREF(Py_None);
6050 return Py_None;
6051 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006052}
6053#endif /* HAVE_SETREUID */
6054
6055#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006057"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058Set the current process's real and effective group ids.");
6059
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006060static PyObject *
6061posix_setregid (PyObject *self, PyObject *args)
6062{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006063 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006064 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6065 _Py_Gid_Converter, &rgid,
6066 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006067 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006068 if (setregid(rgid, egid) < 0) {
6069 return posix_error();
6070 } else {
6071 Py_INCREF(Py_None);
6072 return Py_None;
6073 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006074}
6075#endif /* HAVE_SETREGID */
6076
Guido van Rossumb6775db1994-08-01 11:34:53 +00006077#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006081
Barry Warsaw53699e91996-12-10 23:23:01 +00006082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006084{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006085 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006086 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006087 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006088 if (setgid(gid) < 0)
6089 return posix_error();
6090 Py_INCREF(Py_None);
6091 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006092}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006093#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006094
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006095#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006097"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006099
6100static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006101posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006102{
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006103 Py_ssize_t i, len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006104 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006105
Victor Stinnerd6f85422010-05-05 23:33:33 +00006106 if (!PySequence_Check(groups)) {
6107 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6108 return NULL;
6109 }
6110 len = PySequence_Size(groups);
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006111 if (len < 0) {
6112 return NULL;
6113 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006114 if (len > MAX_GROUPS) {
6115 PyErr_SetString(PyExc_ValueError, "too many groups");
6116 return NULL;
6117 }
6118 for(i = 0; i < len; i++) {
6119 PyObject *elem;
6120 elem = PySequence_GetItem(groups, i);
6121 if (!elem)
6122 return NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006123 if (!PyInt_Check(elem) && !PyLong_Check(elem)) {
6124 PyErr_SetString(PyExc_TypeError,
6125 "groups must be integers");
6126 Py_DECREF(elem);
6127 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006128 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006129 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006130 Py_DECREF(elem);
6131 return NULL;
6132 }
6133 }
6134 Py_DECREF(elem);
6135 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006136
Victor Stinnerd6f85422010-05-05 23:33:33 +00006137 if (setgroups(len, grouplist) < 0)
6138 return posix_error();
6139 Py_INCREF(Py_None);
6140 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006141}
6142#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006143
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006144#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006145static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006146wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006147{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006148 PyObject *result;
6149 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006150
Victor Stinnerd6f85422010-05-05 23:33:33 +00006151 if (pid == -1)
6152 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006153
Victor Stinnerd6f85422010-05-05 23:33:33 +00006154 if (struct_rusage == NULL) {
6155 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6156 if (m == NULL)
6157 return NULL;
6158 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6159 Py_DECREF(m);
6160 if (struct_rusage == NULL)
6161 return NULL;
6162 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006163
Victor Stinnerd6f85422010-05-05 23:33:33 +00006164 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6165 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6166 if (!result)
6167 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006168
6169#ifndef doubletime
6170#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6171#endif
6172
Victor Stinnerd6f85422010-05-05 23:33:33 +00006173 PyStructSequence_SET_ITEM(result, 0,
6174 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6175 PyStructSequence_SET_ITEM(result, 1,
6176 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006177#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006178 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6179 SET_INT(result, 2, ru->ru_maxrss);
6180 SET_INT(result, 3, ru->ru_ixrss);
6181 SET_INT(result, 4, ru->ru_idrss);
6182 SET_INT(result, 5, ru->ru_isrss);
6183 SET_INT(result, 6, ru->ru_minflt);
6184 SET_INT(result, 7, ru->ru_majflt);
6185 SET_INT(result, 8, ru->ru_nswap);
6186 SET_INT(result, 9, ru->ru_inblock);
6187 SET_INT(result, 10, ru->ru_oublock);
6188 SET_INT(result, 11, ru->ru_msgsnd);
6189 SET_INT(result, 12, ru->ru_msgrcv);
6190 SET_INT(result, 13, ru->ru_nsignals);
6191 SET_INT(result, 14, ru->ru_nvcsw);
6192 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006193#undef SET_INT
6194
Victor Stinnerd6f85422010-05-05 23:33:33 +00006195 if (PyErr_Occurred()) {
6196 Py_DECREF(result);
6197 return NULL;
6198 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006199
Victor Stinnerd6f85422010-05-05 23:33:33 +00006200 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006201}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006202#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006203
6204#ifdef HAVE_WAIT3
6205PyDoc_STRVAR(posix_wait3__doc__,
6206"wait3(options) -> (pid, status, rusage)\n\n\
6207Wait for completion of a child process.");
6208
6209static PyObject *
6210posix_wait3(PyObject *self, PyObject *args)
6211{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006212 pid_t pid;
6213 int options;
6214 struct rusage ru;
6215 WAIT_TYPE status;
6216 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006217
Victor Stinnerd6f85422010-05-05 23:33:33 +00006218 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6219 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006220
Victor Stinnerd6f85422010-05-05 23:33:33 +00006221 Py_BEGIN_ALLOW_THREADS
6222 pid = wait3(&status, options, &ru);
6223 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006224
Victor Stinnerd6f85422010-05-05 23:33:33 +00006225 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006226}
6227#endif /* HAVE_WAIT3 */
6228
6229#ifdef HAVE_WAIT4
6230PyDoc_STRVAR(posix_wait4__doc__,
6231"wait4(pid, options) -> (pid, status, rusage)\n\n\
6232Wait for completion of a given child process.");
6233
6234static PyObject *
6235posix_wait4(PyObject *self, PyObject *args)
6236{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006237 pid_t pid;
6238 int options;
6239 struct rusage ru;
6240 WAIT_TYPE status;
6241 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006242
Victor Stinnerd6f85422010-05-05 23:33:33 +00006243 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6244 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006245
Victor Stinnerd6f85422010-05-05 23:33:33 +00006246 Py_BEGIN_ALLOW_THREADS
6247 pid = wait4(pid, &status, options, &ru);
6248 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006249
Victor Stinnerd6f85422010-05-05 23:33:33 +00006250 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006251}
6252#endif /* HAVE_WAIT4 */
6253
Guido van Rossumb6775db1994-08-01 11:34:53 +00006254#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006255PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006256"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006258
Barry Warsaw53699e91996-12-10 23:23:01 +00006259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006260posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006261{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006262 pid_t pid;
6263 int options;
6264 WAIT_TYPE status;
6265 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006266
Victor Stinnerd6f85422010-05-05 23:33:33 +00006267 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6268 return NULL;
6269 Py_BEGIN_ALLOW_THREADS
6270 pid = waitpid(pid, &status, options);
6271 Py_END_ALLOW_THREADS
6272 if (pid == -1)
6273 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006274
Victor Stinnerd6f85422010-05-05 23:33:33 +00006275 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006276}
6277
Tim Petersab034fa2002-02-01 11:27:43 +00006278#elif defined(HAVE_CWAIT)
6279
6280/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006281PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006282"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006284
6285static PyObject *
6286posix_waitpid(PyObject *self, PyObject *args)
6287{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006288 Py_intptr_t pid;
6289 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006290
Victor Stinnerd6f85422010-05-05 23:33:33 +00006291 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6292 return NULL;
6293 Py_BEGIN_ALLOW_THREADS
6294 pid = _cwait(&status, pid, options);
6295 Py_END_ALLOW_THREADS
6296 if (pid == -1)
6297 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006298
Victor Stinnerd6f85422010-05-05 23:33:33 +00006299 /* shift the status left a byte so this is more like the POSIX waitpid */
6300 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006301}
6302#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006303
Guido van Rossumad0ee831995-03-01 10:34:45 +00006304#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006306"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006307Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006308
Barry Warsaw53699e91996-12-10 23:23:01 +00006309static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006310posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006311{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006312 pid_t pid;
6313 WAIT_TYPE status;
6314 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006315
Victor Stinnerd6f85422010-05-05 23:33:33 +00006316 Py_BEGIN_ALLOW_THREADS
6317 pid = wait(&status);
6318 Py_END_ALLOW_THREADS
6319 if (pid == -1)
6320 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006321
Victor Stinnerd6f85422010-05-05 23:33:33 +00006322 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006323}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006324#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006328"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006330
Barry Warsaw53699e91996-12-10 23:23:01 +00006331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006332posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006333{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006334#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006335 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006336#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006337#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006338 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006339#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006340 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006341#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006343}
6344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006345
Guido van Rossumb6775db1994-08-01 11:34:53 +00006346#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006348"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006349Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006350
Barry Warsaw53699e91996-12-10 23:23:01 +00006351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006352posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006353{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006354 PyObject* v;
6355 char buf[MAXPATHLEN];
6356 char *path;
6357 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006358#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006359 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006360#endif
6361
Victor Stinnerd6f85422010-05-05 23:33:33 +00006362 if (!PyArg_ParseTuple(args, "et:readlink",
6363 Py_FileSystemDefaultEncoding, &path))
6364 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006365#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006366 v = PySequence_GetItem(args, 0);
6367 if (v == NULL) {
6368 PyMem_Free(path);
6369 return NULL;
6370 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006371
Victor Stinnerd6f85422010-05-05 23:33:33 +00006372 if (PyUnicode_Check(v)) {
6373 arg_is_unicode = 1;
6374 }
6375 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006376#endif
6377
Victor Stinnerd6f85422010-05-05 23:33:33 +00006378 Py_BEGIN_ALLOW_THREADS
6379 n = readlink(path, buf, (int) sizeof buf);
6380 Py_END_ALLOW_THREADS
6381 if (n < 0)
6382 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006383
Victor Stinnerd6f85422010-05-05 23:33:33 +00006384 PyMem_Free(path);
6385 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006386#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006387 if (arg_is_unicode) {
6388 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006389
Victor Stinnerd6f85422010-05-05 23:33:33 +00006390 w = PyUnicode_FromEncodedObject(v,
6391 Py_FileSystemDefaultEncoding,
6392 "strict");
6393 if (w != NULL) {
6394 Py_DECREF(v);
6395 v = w;
6396 }
6397 else {
6398 /* fall back to the original byte string, as
6399 discussed in patch #683592 */
6400 PyErr_Clear();
6401 }
6402 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006403#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006404 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006406#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006408
Guido van Rossumb6775db1994-08-01 11:34:53 +00006409#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006410PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006411"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006412Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006413
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006414static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006415posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006416{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006417 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006418}
6419#endif /* HAVE_SYMLINK */
6420
6421
6422#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006423#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6424static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006425system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006426{
6427 ULONG value = 0;
6428
6429 Py_BEGIN_ALLOW_THREADS
6430 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6431 Py_END_ALLOW_THREADS
6432
6433 return value;
6434}
6435
6436static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006437posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006438{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006439 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006440 return Py_BuildValue("ddddd",
6441 (double)0 /* t.tms_utime / HZ */,
6442 (double)0 /* t.tms_stime / HZ */,
6443 (double)0 /* t.tms_cutime / HZ */,
6444 (double)0 /* t.tms_cstime / HZ */,
6445 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006446}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006447#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006448#define NEED_TICKS_PER_SECOND
6449static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006450static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006451posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006452{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006453 struct tms t;
6454 clock_t c;
6455 errno = 0;
6456 c = times(&t);
6457 if (c == (clock_t) -1)
6458 return posix_error();
6459 return Py_BuildValue("ddddd",
6460 (double)t.tms_utime / ticks_per_second,
6461 (double)t.tms_stime / ticks_per_second,
6462 (double)t.tms_cutime / ticks_per_second,
6463 (double)t.tms_cstime / ticks_per_second,
6464 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006465}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006466#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006467#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006468
6469
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006470#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006471#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006473posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006474{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006475 FILETIME create, exit, kernel, user;
6476 HANDLE hProc;
6477 hProc = GetCurrentProcess();
6478 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6479 /* The fields of a FILETIME structure are the hi and lo part
6480 of a 64-bit value expressed in 100 nanosecond units.
6481 1e7 is one second in such units; 1e-7 the inverse.
6482 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6483 */
6484 return Py_BuildValue(
6485 "ddddd",
6486 (double)(user.dwHighDateTime*429.4967296 +
6487 user.dwLowDateTime*1e-7),
6488 (double)(kernel.dwHighDateTime*429.4967296 +
6489 kernel.dwLowDateTime*1e-7),
6490 (double)0,
6491 (double)0,
6492 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006493}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006494#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006495
6496#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006497PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006498"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006500#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006502
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006503#ifdef HAVE_GETSID
6504PyDoc_STRVAR(posix_getsid__doc__,
6505"getsid(pid) -> sid\n\n\
6506Call the system call getsid().");
6507
6508static PyObject *
6509posix_getsid(PyObject *self, PyObject *args)
6510{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006511 pid_t pid;
6512 int sid;
6513 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6514 return NULL;
6515 sid = getsid(pid);
6516 if (sid < 0)
6517 return posix_error();
6518 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006519}
6520#endif /* HAVE_GETSID */
6521
6522
Guido van Rossumb6775db1994-08-01 11:34:53 +00006523#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006525"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006526Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Barry Warsaw53699e91996-12-10 23:23:01 +00006528static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006529posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006530{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006531 if (setsid() < 0)
6532 return posix_error();
6533 Py_INCREF(Py_None);
6534 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006535}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006536#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006537
Guido van Rossumb6775db1994-08-01 11:34:53 +00006538#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006539PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006540"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006541Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006542
Barry Warsaw53699e91996-12-10 23:23:01 +00006543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006544posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006545{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006546 pid_t pid;
6547 int pgrp;
6548 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6549 return NULL;
6550 if (setpgid(pid, pgrp) < 0)
6551 return posix_error();
6552 Py_INCREF(Py_None);
6553 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006554}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006555#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006557
Guido van Rossumb6775db1994-08-01 11:34:53 +00006558#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006560"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006561Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006562
Barry Warsaw53699e91996-12-10 23:23:01 +00006563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006564posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006565{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006566 int fd;
6567 pid_t pgid;
6568 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6569 return NULL;
6570 pgid = tcgetpgrp(fd);
6571 if (pgid < 0)
6572 return posix_error();
6573 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006574}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006575#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006577
Guido van Rossumb6775db1994-08-01 11:34:53 +00006578#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006579PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006580"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006581Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006582
Barry Warsaw53699e91996-12-10 23:23:01 +00006583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006584posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006585{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006586 int fd;
6587 pid_t pgid;
6588 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6589 return NULL;
6590 if (tcsetpgrp(fd, pgid) < 0)
6591 return posix_error();
6592 Py_INCREF(Py_None);
6593 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006594}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006595#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006596
Guido van Rossum687dd131993-05-17 08:34:16 +00006597/* Functions acting on file descriptors */
6598
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006599PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006600"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006602
Barry Warsaw53699e91996-12-10 23:23:01 +00006603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006604posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006605{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006606 char *file = NULL;
6607 int flag;
6608 int mode = 0777;
6609 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006610
6611#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006612 Py_UNICODE *wpath;
6613 if (PyArg_ParseTuple(args, "ui|i:mkdir", &wpath, &flag, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006614 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006615 fd = _wopen(wpath, flag, mode);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006616 Py_END_ALLOW_THREADS
6617 if (fd < 0)
6618 return posix_error();
6619 return PyInt_FromLong((long)fd);
6620 }
6621 /* Drop the argument parsing error as narrow strings
6622 are also valid. */
6623 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006624#endif
6625
Victor Stinnerd6f85422010-05-05 23:33:33 +00006626 if (!PyArg_ParseTuple(args, "eti|i",
6627 Py_FileSystemDefaultEncoding, &file,
6628 &flag, &mode))
6629 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006630
Victor Stinnerd6f85422010-05-05 23:33:33 +00006631 Py_BEGIN_ALLOW_THREADS
6632 fd = open(file, flag, mode);
6633 Py_END_ALLOW_THREADS
6634 if (fd < 0)
6635 return posix_error_with_allocated_filename(file);
6636 PyMem_Free(file);
6637 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006638}
6639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006642"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006643Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006644
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006645/*
6646The underscore at end of function name avoids a name clash with the libc
6647function posix_close.
6648*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006649static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006650posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006651{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006652 int fd, res;
6653 if (!PyArg_ParseTuple(args, "i:close", &fd))
6654 return NULL;
6655 if (!_PyVerify_fd(fd))
6656 return posix_error();
6657 Py_BEGIN_ALLOW_THREADS
6658 res = close(fd);
6659 Py_END_ALLOW_THREADS
6660 if (res < 0)
6661 return posix_error();
6662 Py_INCREF(Py_None);
6663 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006664}
6665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006666
Victor Stinnerd6f85422010-05-05 23:33:33 +00006667PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006668"closerange(fd_low, fd_high)\n\n\
6669Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6670
6671static PyObject *
6672posix_closerange(PyObject *self, PyObject *args)
6673{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006674 int fd_from, fd_to, i;
6675 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6676 return NULL;
6677 Py_BEGIN_ALLOW_THREADS
6678 for (i = fd_from; i < fd_to; i++)
6679 if (_PyVerify_fd(i))
6680 close(i);
6681 Py_END_ALLOW_THREADS
6682 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006683}
6684
6685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006686PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006687"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006688Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006689
Barry Warsaw53699e91996-12-10 23:23:01 +00006690static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006691posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006692{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006693 int fd;
6694 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6695 return NULL;
6696 if (!_PyVerify_fd(fd))
6697 return posix_error();
6698 Py_BEGIN_ALLOW_THREADS
6699 fd = dup(fd);
6700 Py_END_ALLOW_THREADS
6701 if (fd < 0)
6702 return posix_error();
6703 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006704}
6705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006706
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006708"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006713{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006714 int fd, fd2, res;
6715 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6716 return NULL;
6717 if (!_PyVerify_fd_dup2(fd, fd2))
6718 return posix_error();
6719 Py_BEGIN_ALLOW_THREADS
6720 res = dup2(fd, fd2);
6721 Py_END_ALLOW_THREADS
6722 if (res < 0)
6723 return posix_error();
6724 Py_INCREF(Py_None);
6725 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006726}
6727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006729PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006730"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006731Set the current position of a file descriptor.\n\
6732Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006733
Barry Warsaw53699e91996-12-10 23:23:01 +00006734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006735posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006736{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006737 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006738#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006739 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006740#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006741 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006742#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006743 PyObject *posobj;
6744 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6745 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006746#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006747 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6748 switch (how) {
6749 case 0: how = SEEK_SET; break;
6750 case 1: how = SEEK_CUR; break;
6751 case 2: how = SEEK_END; break;
6752 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006753#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006754
6755#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006756 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006757#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006758 pos = PyLong_Check(posobj) ?
6759 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006760#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006761 if (PyErr_Occurred())
6762 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006763
Victor Stinnerd6f85422010-05-05 23:33:33 +00006764 if (!_PyVerify_fd(fd))
6765 return posix_error();
6766 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006767#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006768 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006769#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006770 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006771#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006772 Py_END_ALLOW_THREADS
6773 if (res < 0)
6774 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006775
6776#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006777 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006778#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006779 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006780#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006781}
6782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006783
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006785"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006786Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006787
Barry Warsaw53699e91996-12-10 23:23:01 +00006788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006789posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006790{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006791 int fd, size, n;
6792 PyObject *buffer;
6793 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6794 return NULL;
6795 if (size < 0) {
6796 errno = EINVAL;
6797 return posix_error();
6798 }
6799 buffer = PyString_FromStringAndSize((char *)NULL, size);
6800 if (buffer == NULL)
6801 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006802 if (!_PyVerify_fd(fd)) {
6803 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006804 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006805 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006806 Py_BEGIN_ALLOW_THREADS
6807 n = read(fd, PyString_AsString(buffer), size);
6808 Py_END_ALLOW_THREADS
6809 if (n < 0) {
6810 Py_DECREF(buffer);
6811 return posix_error();
6812 }
6813 if (n != size)
6814 _PyString_Resize(&buffer, n);
6815 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006816}
6817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006819PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006820"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006821Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006822
Barry Warsaw53699e91996-12-10 23:23:01 +00006823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006824posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006825{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006826 Py_buffer pbuf;
6827 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006828 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006829
Victor Stinnerd6f85422010-05-05 23:33:33 +00006830 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6831 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006832 if (!_PyVerify_fd(fd)) {
6833 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006834 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006835 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006836 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006837 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006838#if defined(MS_WIN64) || defined(MS_WINDOWS)
6839 if (len > INT_MAX)
6840 len = INT_MAX;
6841 size = write(fd, pbuf.buf, (int)len);
6842#else
6843 size = write(fd, pbuf.buf, len);
6844#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006845 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006846 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006847 if (size < 0)
6848 return posix_error();
6849 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006850}
6851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006853PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006854"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006855Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006856
Barry Warsaw53699e91996-12-10 23:23:01 +00006857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006858posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006859{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006860 int fd;
6861 STRUCT_STAT st;
6862 int res;
6863 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6864 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006865#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006866 /* on OpenVMS we must ensure that all bytes are written to the file */
6867 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006868#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006869 if (!_PyVerify_fd(fd))
6870 return posix_error();
6871 Py_BEGIN_ALLOW_THREADS
6872 res = FSTAT(fd, &st);
6873 Py_END_ALLOW_THREADS
6874 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006875#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006876 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006877#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006878 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006879#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006880 }
Tim Peters5aa91602002-01-30 05:46:57 +00006881
Victor Stinnerd6f85422010-05-05 23:33:33 +00006882 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006883}
6884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006885
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006886PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006887"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006888Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006889
Barry Warsaw53699e91996-12-10 23:23:01 +00006890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006891posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006892{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006893 int fd;
6894 char *orgmode = "r";
6895 int bufsize = -1;
6896 FILE *fp;
6897 PyObject *f;
6898 char *mode;
6899 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6900 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006901
Victor Stinnerd6f85422010-05-05 23:33:33 +00006902 /* Sanitize mode. See fileobject.c */
6903 mode = PyMem_MALLOC(strlen(orgmode)+3);
6904 if (!mode) {
6905 PyErr_NoMemory();
6906 return NULL;
6907 }
6908 strcpy(mode, orgmode);
6909 if (_PyFile_SanitizeMode(mode)) {
6910 PyMem_FREE(mode);
6911 return NULL;
6912 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006913 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006914 PyMem_FREE(mode);
6915 return posix_error();
6916 }
6917#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6918 {
6919 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006920 const char *msg;
6921 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006922 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6923 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006924 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006925 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006926 EISDIR, msg, "<fdopen>");
6927 if (exc) {
6928 PyErr_SetObject(PyExc_IOError, exc);
6929 Py_DECREF(exc);
6930 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006931 return NULL;
6932 }
6933 }
6934#endif
Benjamin Petersond3035d52016-12-03 13:03:18 -08006935 /* The dummy filename used here must be kept in sync with the value
6936 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6937 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
Benjamin Petersone95048e2016-12-03 13:05:40 -08006938 if (f == NULL) {
Benjamin Peterson9ea8faf2016-12-03 13:07:47 -08006939 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006940 return NULL;
Benjamin Petersone95048e2016-12-03 13:05:40 -08006941 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006942 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006943#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006944 if (mode[0] == 'a') {
6945 /* try to make sure the O_APPEND flag is set */
6946 int flags;
6947 flags = fcntl(fd, F_GETFL);
6948 if (flags != -1)
6949 fcntl(fd, F_SETFL, flags | O_APPEND);
6950 fp = fdopen(fd, mode);
6951 if (fp == NULL && flags != -1)
6952 /* restore old mode if fdopen failed */
6953 fcntl(fd, F_SETFL, flags);
6954 } else {
6955 fp = fdopen(fd, mode);
6956 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006957#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006958 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006959#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006960 Py_END_ALLOW_THREADS
6961 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006962 if (fp == NULL) {
6963 Py_DECREF(f);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006964 return posix_error();
Benjamin Petersond3035d52016-12-03 13:03:18 -08006965 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006966 /* We now know we will succeed, so initialize the file object. */
6967 ((PyFileObject *)f)->f_fp = fp;
6968 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006969 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006970}
6971
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006972PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006973"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006974Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006975connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006976
6977static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006978posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006979{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006980 int fd;
6981 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6982 return NULL;
6983 if (!_PyVerify_fd(fd))
6984 return PyBool_FromLong(0);
6985 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006986}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006987
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006988#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006989PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006990"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006991Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006992
Barry Warsaw53699e91996-12-10 23:23:01 +00006993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006994posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006995{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006996#if defined(PYOS_OS2)
6997 HFILE read, write;
6998 APIRET rc;
6999
Victor Stinnerd6f85422010-05-05 23:33:33 +00007000 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007001 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007002 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007003 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007004 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007005
7006 return Py_BuildValue("(ii)", read, write);
7007#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007008#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007009 int fds[2];
7010 int res;
7011 Py_BEGIN_ALLOW_THREADS
7012 res = pipe(fds);
7013 Py_END_ALLOW_THREADS
7014 if (res != 0)
7015 return posix_error();
7016 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007017#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00007018 HANDLE read, write;
7019 int read_fd, write_fd;
7020 BOOL ok;
7021 Py_BEGIN_ALLOW_THREADS
7022 ok = CreatePipe(&read, &write, NULL, 0);
7023 Py_END_ALLOW_THREADS
7024 if (!ok)
7025 return win32_error("CreatePipe", NULL);
7026 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7027 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7028 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007029#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007030#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007031}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007032#endif /* HAVE_PIPE */
7033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007034
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007035#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007036PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007037"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007038Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007039
Barry Warsaw53699e91996-12-10 23:23:01 +00007040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007041posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007042{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007043 char *filename;
7044 int mode = 0666;
7045 int res;
7046 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7047 return NULL;
7048 Py_BEGIN_ALLOW_THREADS
7049 res = mkfifo(filename, mode);
7050 Py_END_ALLOW_THREADS
7051 if (res < 0)
7052 return posix_error();
7053 Py_INCREF(Py_None);
7054 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007055}
7056#endif
7057
7058
Neal Norwitz11690112002-07-30 01:08:28 +00007059#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007061"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007062Create a filesystem node (file, device special file or named pipe)\n\
7063named filename. mode specifies both the permissions to use and the\n\
7064type of node to be created, being combined (bitwise OR) with one of\n\
7065S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007066device defines the newly created device special file (probably using\n\
7067os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007068
7069
7070static PyObject *
7071posix_mknod(PyObject *self, PyObject *args)
7072{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007073 char *filename;
7074 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007075 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007076 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007077 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7078 &filename, &mode,
7079 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007080 return NULL;
7081 Py_BEGIN_ALLOW_THREADS
7082 res = mknod(filename, mode, device);
7083 Py_END_ALLOW_THREADS
7084 if (res < 0)
7085 return posix_error();
7086 Py_INCREF(Py_None);
7087 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007088}
7089#endif
7090
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007091#ifdef HAVE_DEVICE_MACROS
7092PyDoc_STRVAR(posix_major__doc__,
7093"major(device) -> major number\n\
7094Extracts a device major number from a raw device number.");
7095
7096static PyObject *
7097posix_major(PyObject *self, PyObject *args)
7098{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007099 dev_t device;
7100 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007101 return NULL;
7102 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007103}
7104
7105PyDoc_STRVAR(posix_minor__doc__,
7106"minor(device) -> minor number\n\
7107Extracts a device minor number from a raw device number.");
7108
7109static PyObject *
7110posix_minor(PyObject *self, PyObject *args)
7111{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007112 dev_t device;
7113 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007114 return NULL;
7115 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007116}
7117
7118PyDoc_STRVAR(posix_makedev__doc__,
7119"makedev(major, minor) -> device number\n\
7120Composes a raw device number from the major and minor device numbers.");
7121
7122static PyObject *
7123posix_makedev(PyObject *self, PyObject *args)
7124{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007125 int major, minor;
7126 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7127 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007128 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007129}
7130#endif /* device macros */
7131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007132
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007133#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007134PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007135"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007136Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007137
Barry Warsaw53699e91996-12-10 23:23:01 +00007138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007139posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007140{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007141 int fd;
7142 off_t length;
7143 int res;
7144 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007145
Victor Stinnerd6f85422010-05-05 23:33:33 +00007146 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7147 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007148
7149#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007150 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007151#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007152 length = PyLong_Check(lenobj) ?
7153 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007154#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007155 if (PyErr_Occurred())
7156 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007157
Victor Stinnerd6f85422010-05-05 23:33:33 +00007158 Py_BEGIN_ALLOW_THREADS
7159 res = ftruncate(fd, length);
7160 Py_END_ALLOW_THREADS
7161 if (res < 0)
7162 return posix_error();
7163 Py_INCREF(Py_None);
7164 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007165}
7166#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007167
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007168#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007170"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007171Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007172
Fred Drake762e2061999-08-26 17:23:54 +00007173/* Save putenv() parameters as values here, so we can collect them when they
7174 * get re-set with another call for the same key. */
7175static PyObject *posix_putenv_garbage;
7176
Tim Peters5aa91602002-01-30 05:46:57 +00007177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007178posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007179{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007180 char *s1, *s2;
7181 char *newenv;
7182 PyObject *newstr;
7183 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007184
Victor Stinnerd6f85422010-05-05 23:33:33 +00007185 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7186 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007187
7188#if defined(PYOS_OS2)
7189 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7190 APIRET rc;
7191
Guido van Rossumd48f2521997-12-05 22:19:34 +00007192 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7193 if (rc != NO_ERROR)
7194 return os2_error(rc);
7195
7196 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7197 APIRET rc;
7198
Guido van Rossumd48f2521997-12-05 22:19:34 +00007199 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7200 if (rc != NO_ERROR)
7201 return os2_error(rc);
7202 } else {
7203#endif
7204
Serhiy Storchaka787826c2017-06-25 09:50:00 +03007205 /* Search from index 1 because on Windows starting '=' is allowed for
7206 defining hidden environment variables. */
7207 if (*s1 == '\0' || strchr(s1 + 1, '=') != NULL) {
7208 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
7209 return NULL;
7210 }
7211
Victor Stinnerd6f85422010-05-05 23:33:33 +00007212 /* XXX This can leak memory -- not easy to fix :-( */
7213 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007214#ifdef MS_WINDOWS
7215 if (_MAX_ENV < (len - 1)) {
7216 PyErr_Format(PyExc_ValueError,
7217 "the environment variable is longer than %u bytes",
7218 _MAX_ENV);
7219 return NULL;
7220 }
7221#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007222 /* len includes space for a trailing \0; the size arg to
7223 PyString_FromStringAndSize does not count that */
7224 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7225 if (newstr == NULL)
7226 return PyErr_NoMemory();
7227 newenv = PyString_AS_STRING(newstr);
7228 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7229 if (putenv(newenv)) {
7230 Py_DECREF(newstr);
7231 posix_error();
7232 return NULL;
7233 }
7234 /* Install the first arg and newstr in posix_putenv_garbage;
7235 * this will cause previous value to be collected. This has to
7236 * happen after the real putenv() call because the old value
7237 * was still accessible until then. */
7238 if (PyDict_SetItem(posix_putenv_garbage,
7239 PyTuple_GET_ITEM(args, 0), newstr)) {
7240 /* really not much we can do; just leak */
7241 PyErr_Clear();
7242 }
7243 else {
7244 Py_DECREF(newstr);
7245 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007246
7247#if defined(PYOS_OS2)
7248 }
7249#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007250 Py_INCREF(Py_None);
7251 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007252}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007253#endif /* putenv */
7254
Guido van Rossumc524d952001-10-19 01:31:59 +00007255#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007256PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007257"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007258Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007259
7260static PyObject *
7261posix_unsetenv(PyObject *self, PyObject *args)
7262{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007263 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007264#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007265 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007266#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007267
Victor Stinnerd6f85422010-05-05 23:33:33 +00007268 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7269 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007270
Charles-François Natali93a11752011-11-27 13:01:35 +01007271#ifdef HAVE_BROKEN_UNSETENV
7272 unsetenv(s1);
7273#else
Victor Stinner53853c32011-11-22 22:20:13 +01007274 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007275 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007276 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007277#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007278
Victor Stinnerd6f85422010-05-05 23:33:33 +00007279 /* Remove the key from posix_putenv_garbage;
7280 * this will cause it to be collected. This has to
7281 * happen after the real unsetenv() call because the
7282 * old value was still accessible until then.
7283 */
7284 if (PyDict_DelItem(posix_putenv_garbage,
7285 PyTuple_GET_ITEM(args, 0))) {
7286 /* really not much we can do; just leak */
7287 PyErr_Clear();
7288 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007289
Victor Stinnerd6f85422010-05-05 23:33:33 +00007290 Py_INCREF(Py_None);
7291 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007292}
7293#endif /* unsetenv */
7294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007295PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007296"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007297Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007298
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007300posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007301{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007302 int code;
7303 char *message;
7304 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7305 return NULL;
7306 message = strerror(code);
7307 if (message == NULL) {
7308 PyErr_SetString(PyExc_ValueError,
7309 "strerror() argument out of range");
7310 return NULL;
7311 }
7312 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007313}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007314
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007315
Guido van Rossumc9641791998-08-04 15:26:23 +00007316#ifdef HAVE_SYS_WAIT_H
7317
Fred Drake106c1a02002-04-23 15:58:02 +00007318#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007319PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007320"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007321Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007322
7323static PyObject *
7324posix_WCOREDUMP(PyObject *self, PyObject *args)
7325{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007326 WAIT_TYPE status;
7327 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007328
Victor Stinnerd6f85422010-05-05 23:33:33 +00007329 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7330 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007331
Victor Stinnerd6f85422010-05-05 23:33:33 +00007332 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007333}
7334#endif /* WCOREDUMP */
7335
7336#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007337PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007338"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007339Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007340job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007341
7342static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007343posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007344{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007345 WAIT_TYPE status;
7346 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007347
Victor Stinnerd6f85422010-05-05 23:33:33 +00007348 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7349 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007350
Victor Stinnerd6f85422010-05-05 23:33:33 +00007351 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007352}
7353#endif /* WIFCONTINUED */
7354
Guido van Rossumc9641791998-08-04 15:26:23 +00007355#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007356PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007357"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007358Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007359
7360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007361posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007362{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007363 WAIT_TYPE status;
7364 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007365
Victor Stinnerd6f85422010-05-05 23:33:33 +00007366 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7367 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007368
Victor Stinnerd6f85422010-05-05 23:33:33 +00007369 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007370}
7371#endif /* WIFSTOPPED */
7372
7373#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007375"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007377
7378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007379posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007380{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007381 WAIT_TYPE status;
7382 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007383
Victor Stinnerd6f85422010-05-05 23:33:33 +00007384 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7385 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007386
Victor Stinnerd6f85422010-05-05 23:33:33 +00007387 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007388}
7389#endif /* WIFSIGNALED */
7390
7391#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007392PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007393"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007394Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007395system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007396
7397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007398posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007399{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007400 WAIT_TYPE status;
7401 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007402
Victor Stinnerd6f85422010-05-05 23:33:33 +00007403 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7404 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007405
Victor Stinnerd6f85422010-05-05 23:33:33 +00007406 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007407}
7408#endif /* WIFEXITED */
7409
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007410#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007411PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007412"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007413Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007414
7415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007416posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007417{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007418 WAIT_TYPE status;
7419 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007420
Victor Stinnerd6f85422010-05-05 23:33:33 +00007421 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7422 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007423
Victor Stinnerd6f85422010-05-05 23:33:33 +00007424 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007425}
7426#endif /* WEXITSTATUS */
7427
7428#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007429PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007430"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007431Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007432value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007433
7434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007435posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007436{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007437 WAIT_TYPE status;
7438 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007439
Victor Stinnerd6f85422010-05-05 23:33:33 +00007440 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7441 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007442
Victor Stinnerd6f85422010-05-05 23:33:33 +00007443 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007444}
7445#endif /* WTERMSIG */
7446
7447#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007448PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007449"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007450Return the signal that stopped the process that provided\n\
7451the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007452
7453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007454posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007455{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007456 WAIT_TYPE status;
7457 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007458
Victor Stinnerd6f85422010-05-05 23:33:33 +00007459 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7460 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007461
Victor Stinnerd6f85422010-05-05 23:33:33 +00007462 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007463}
7464#endif /* WSTOPSIG */
7465
7466#endif /* HAVE_SYS_WAIT_H */
7467
7468
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007469#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007470#ifdef _SCO_DS
7471/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7472 needed definitions in sys/statvfs.h */
7473#define _SVID3
7474#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007475#include <sys/statvfs.h>
7476
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007477static PyObject*
7478_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007479 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7480 if (v == NULL)
7481 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007482
7483#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007484 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7485 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7486 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7487 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7488 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7489 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7490 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7491 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7492 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7493 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007494#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007495 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7496 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7497 PyStructSequence_SET_ITEM(v, 2,
7498 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7499 PyStructSequence_SET_ITEM(v, 3,
7500 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7501 PyStructSequence_SET_ITEM(v, 4,
7502 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7503 PyStructSequence_SET_ITEM(v, 5,
7504 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7505 PyStructSequence_SET_ITEM(v, 6,
7506 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7507 PyStructSequence_SET_ITEM(v, 7,
7508 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7509 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7510 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007511#endif
7512
Victor Stinnerd6f85422010-05-05 23:33:33 +00007513 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007514}
7515
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007516PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007517"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007518Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007519
7520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007521posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007522{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007523 int fd, res;
7524 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007525
Victor Stinnerd6f85422010-05-05 23:33:33 +00007526 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7527 return NULL;
7528 Py_BEGIN_ALLOW_THREADS
7529 res = fstatvfs(fd, &st);
7530 Py_END_ALLOW_THREADS
7531 if (res != 0)
7532 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007533
Victor Stinnerd6f85422010-05-05 23:33:33 +00007534 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007535}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007536#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007537
7538
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007539#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007540#include <sys/statvfs.h>
7541
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007542PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007543"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007544Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007545
7546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007547posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007548{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007549 char *path;
7550 int res;
7551 struct statvfs st;
7552 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7553 return NULL;
7554 Py_BEGIN_ALLOW_THREADS
7555 res = statvfs(path, &st);
7556 Py_END_ALLOW_THREADS
7557 if (res != 0)
7558 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007559
Victor Stinnerd6f85422010-05-05 23:33:33 +00007560 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007561}
7562#endif /* HAVE_STATVFS */
7563
7564
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007566PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007567"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007568Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007569The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007570or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007571
7572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007573posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574{
7575 PyObject *result = NULL;
7576 char *dir = NULL;
7577 char *pfx = NULL;
7578 char *name;
7579
7580 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007581 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007582
7583 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007584 "tempnam is a potential security risk to your program") < 0)
7585 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007586
Antoine Pitroub0614612011-01-02 20:04:52 +00007587 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7588 "use the tempfile module", 1) < 0)
7589 return NULL;
7590
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007591#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007592 name = _tempnam(dir, pfx);
7593#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007594 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007595#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007596 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007597 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007598 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007599 free(name);
7600 return result;
7601}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007602#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007603
7604
7605#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007606PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007607"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007608Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007609
7610static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007611posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007612{
7613 FILE *fp;
7614
Antoine Pitroub0614612011-01-02 20:04:52 +00007615 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7616 "use the tempfile module", 1) < 0)
7617 return NULL;
7618
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007619 fp = tmpfile();
7620 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007621 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007622 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623}
7624#endif
7625
7626
7627#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007628PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007629"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007630Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007631
7632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007633posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007634{
7635 char buffer[L_tmpnam];
7636 char *name;
7637
Skip Montanaro95618b52001-08-18 18:52:10 +00007638 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007639 "tmpnam is a potential security risk to your program") < 0)
7640 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007641
Antoine Pitroub0614612011-01-02 20:04:52 +00007642 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7643 "use the tempfile module", 1) < 0)
7644 return NULL;
7645
Greg Wardb48bc172000-03-01 21:51:56 +00007646#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007647 name = tmpnam_r(buffer);
7648#else
7649 name = tmpnam(buffer);
7650#endif
7651 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007652 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007653#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007654 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007655#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007656 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007657#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007658 );
7659 PyErr_SetObject(PyExc_OSError, err);
7660 Py_XDECREF(err);
7661 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007662 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007663 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007664}
7665#endif
7666
7667
Fred Drakec9680921999-12-13 16:37:25 +00007668/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7669 * It maps strings representing configuration variable names to
7670 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007671 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007672 * rarely-used constants. There are three separate tables that use
7673 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007674 *
7675 * This code is always included, even if none of the interfaces that
7676 * need it are included. The #if hackery needed to avoid it would be
7677 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007678 */
7679struct constdef {
7680 char *name;
7681 long value;
7682};
7683
Fred Drake12c6e2d1999-12-14 21:25:03 +00007684static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007685conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007686 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007687{
7688 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007689 *valuep = PyInt_AS_LONG(arg);
7690 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007691 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007692 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007693 /* look up the value in the table using a binary search */
7694 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007696 size_t hi = tablesize;
7697 int cmp;
7698 char *confname = PyString_AS_STRING(arg);
7699 while (lo < hi) {
7700 mid = (lo + hi) / 2;
7701 cmp = strcmp(confname, table[mid].name);
7702 if (cmp < 0)
7703 hi = mid;
7704 else if (cmp > 0)
7705 lo = mid + 1;
7706 else {
7707 *valuep = table[mid].value;
7708 return 1;
7709 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007710 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007711 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007712 }
7713 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007714 PyErr_SetString(PyExc_TypeError,
7715 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007716 return 0;
7717}
7718
7719
7720#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7721static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007722#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007723 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007724#endif
7725#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007726 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007727#endif
Fred Drakec9680921999-12-13 16:37:25 +00007728#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007729 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007730#endif
7731#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007732 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007733#endif
7734#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007735 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007736#endif
7737#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007738 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007739#endif
7740#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007741 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007742#endif
7743#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007744 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007745#endif
7746#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007747 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007748#endif
7749#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007750 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007751#endif
7752#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007753 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007754#endif
7755#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007756 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007757#endif
7758#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007759 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007760#endif
7761#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007762 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007763#endif
7764#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007765 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007766#endif
7767#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007768 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007769#endif
7770#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007771 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007772#endif
7773};
7774
Fred Drakec9680921999-12-13 16:37:25 +00007775static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007776conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007777{
7778 return conv_confname(arg, valuep, posix_constants_pathconf,
7779 sizeof(posix_constants_pathconf)
7780 / sizeof(struct constdef));
7781}
7782#endif
7783
7784#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007785PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007786"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007787Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007788If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007789
7790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007791posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007792{
7793 PyObject *result = NULL;
7794 int name, fd;
7795
Fred Drake12c6e2d1999-12-14 21:25:03 +00007796 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7797 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007798 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007799
Stefan Krah93f7a322010-11-26 17:35:50 +00007800 errno = 0;
7801 limit = fpathconf(fd, name);
7802 if (limit == -1 && errno != 0)
7803 posix_error();
7804 else
7805 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007806 }
7807 return result;
7808}
7809#endif
7810
7811
7812#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007813PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007814"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007815Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007816If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007817
7818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007819posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007820{
7821 PyObject *result = NULL;
7822 int name;
7823 char *path;
7824
7825 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7826 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007827 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007828
Victor Stinnerd6f85422010-05-05 23:33:33 +00007829 errno = 0;
7830 limit = pathconf(path, name);
7831 if (limit == -1 && errno != 0) {
7832 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007833 /* could be a path or name problem */
7834 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007835 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007836 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007837 }
7838 else
7839 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007840 }
7841 return result;
7842}
7843#endif
7844
7845#ifdef HAVE_CONFSTR
7846static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007847#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007848 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007849#endif
7850#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007851 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007852#endif
7853#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007854 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007855#endif
7856#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007857 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007858#endif
7859#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007860 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007861#endif
Fred Drakec9680921999-12-13 16:37:25 +00007862#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007863 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007864#endif
7865#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007866 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007867#endif
7868#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007869 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007870#endif
7871#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007872 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007873#endif
7874#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007875 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007876#endif
7877#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007878 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007879#endif
7880#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007881 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007882#endif
7883#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007884 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007885#endif
Fred Draked86ed291999-12-15 15:34:33 +00007886#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007887 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007888#endif
Fred Drakec9680921999-12-13 16:37:25 +00007889#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007890 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007891#endif
Fred Draked86ed291999-12-15 15:34:33 +00007892#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007893 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007894#endif
7895#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007896 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007897#endif
7898#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007899 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007900#endif
7901#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007902 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007903#endif
Fred Drakec9680921999-12-13 16:37:25 +00007904#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007905 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007906#endif
7907#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007908 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007909#endif
7910#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007911 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007912#endif
7913#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007914 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007915#endif
7916#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007917 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007918#endif
7919#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007920 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007921#endif
7922#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007923 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007924#endif
7925#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007926 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007927#endif
7928#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007929 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007930#endif
7931#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007932 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007933#endif
7934#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007935 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007936#endif
7937#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007938 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007939#endif
7940#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007941 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007942#endif
7943#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007944 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007945#endif
7946#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007947 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007948#endif
7949#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007950 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007951#endif
Fred Draked86ed291999-12-15 15:34:33 +00007952#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007953 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007954#endif
7955#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007956 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007957#endif
7958#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007959 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007960#endif
7961#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007962 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007963#endif
7964#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007965 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007966#endif
7967#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007968 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007969#endif
7970#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007971 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007972#endif
7973#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007974 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007975#endif
7976#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007977 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007978#endif
7979#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007980 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007981#endif
7982#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007983 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007984#endif
7985#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007986 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007987#endif
7988#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007989 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007990#endif
Fred Drakec9680921999-12-13 16:37:25 +00007991};
7992
7993static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007994conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007995{
7996 return conv_confname(arg, valuep, posix_constants_confstr,
7997 sizeof(posix_constants_confstr)
7998 / sizeof(struct constdef));
7999}
8000
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008001PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008002"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008003Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008004
8005static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008006posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008007{
8008 PyObject *result = NULL;
8009 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00008010 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00008011
8012 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008013 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008014
Victor Stinnerd6f85422010-05-05 23:33:33 +00008015 errno = 0;
8016 len = confstr(name, buffer, sizeof(buffer));
8017 if (len == 0) {
8018 if (errno) {
8019 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008020 }
8021 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008022 result = Py_None;
8023 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00008024 }
8025 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00008026 else {
8027 if ((unsigned int)len >= sizeof(buffer)) {
8028 result = PyString_FromStringAndSize(NULL, len-1);
8029 if (result != NULL)
8030 confstr(name, PyString_AS_STRING(result), len);
8031 }
8032 else
8033 result = PyString_FromStringAndSize(buffer, len-1);
8034 }
8035 }
Fred Drakec9680921999-12-13 16:37:25 +00008036 return result;
8037}
8038#endif
8039
8040
8041#ifdef HAVE_SYSCONF
8042static struct constdef posix_constants_sysconf[] = {
8043#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008044 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008045#endif
8046#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008047 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008048#endif
8049#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008050 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008051#endif
8052#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008053 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008054#endif
8055#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008056 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008057#endif
8058#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008059 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008060#endif
8061#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008062 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
8064#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008065 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008066#endif
8067#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008068 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008069#endif
8070#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008071 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008072#endif
Fred Draked86ed291999-12-15 15:34:33 +00008073#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008074 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008075#endif
8076#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008077 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008078#endif
Fred Drakec9680921999-12-13 16:37:25 +00008079#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008080 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
Fred Drakec9680921999-12-13 16:37:25 +00008082#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008083 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008084#endif
8085#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008086 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008087#endif
8088#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008089 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008090#endif
8091#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008092 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008093#endif
8094#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008095 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008096#endif
Fred Draked86ed291999-12-15 15:34:33 +00008097#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008098 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008099#endif
Fred Drakec9680921999-12-13 16:37:25 +00008100#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008101 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008102#endif
8103#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008104 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008105#endif
8106#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008107 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008108#endif
8109#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008110 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008111#endif
8112#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008113 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008114#endif
Fred Draked86ed291999-12-15 15:34:33 +00008115#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008116 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008117#endif
Fred Drakec9680921999-12-13 16:37:25 +00008118#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008119 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008120#endif
8121#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008122 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008123#endif
8124#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008125 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008126#endif
8127#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008128 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008129#endif
8130#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008131 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008132#endif
8133#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008134 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008135#endif
8136#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008137 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008138#endif
8139#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008140 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008141#endif
8142#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008143 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008144#endif
8145#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008146 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008147#endif
8148#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008149 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008150#endif
8151#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008152 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008153#endif
8154#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008155 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008156#endif
8157#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008158 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008159#endif
8160#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008161 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008162#endif
8163#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008164 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008165#endif
8166#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008167 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008168#endif
8169#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008170 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008171#endif
8172#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008173 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008174#endif
8175#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008176 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008177#endif
8178#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008179 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008180#endif
8181#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008182 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008183#endif
8184#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008185 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008186#endif
Fred Draked86ed291999-12-15 15:34:33 +00008187#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008188 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008189#endif
Fred Drakec9680921999-12-13 16:37:25 +00008190#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008191 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008192#endif
8193#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008194 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008195#endif
8196#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008197 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008198#endif
Fred Draked86ed291999-12-15 15:34:33 +00008199#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008200 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008201#endif
Fred Drakec9680921999-12-13 16:37:25 +00008202#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008203 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008204#endif
Fred Draked86ed291999-12-15 15:34:33 +00008205#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008206 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008207#endif
8208#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008209 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008210#endif
Fred Drakec9680921999-12-13 16:37:25 +00008211#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008212 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008213#endif
8214#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008215 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008218 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008221 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
Fred Draked86ed291999-12-15 15:34:33 +00008223#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008224 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008225#endif
Fred Drakec9680921999-12-13 16:37:25 +00008226#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008227 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008230 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
8232#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008233 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008234#endif
8235#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008236 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008239 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008242 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008245 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
Fred Draked86ed291999-12-15 15:34:33 +00008247#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008248 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008249#endif
Fred Drakec9680921999-12-13 16:37:25 +00008250#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008251 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008254 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
Fred Draked86ed291999-12-15 15:34:33 +00008256#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008257 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008258#endif
Fred Drakec9680921999-12-13 16:37:25 +00008259#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008260 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008261#endif
8262#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008263 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008264#endif
8265#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008266 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008267#endif
8268#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008269 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008270#endif
8271#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008272 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008273#endif
8274#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008275 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
8277#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008278 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008281 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008284 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
Fred Draked86ed291999-12-15 15:34:33 +00008286#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008287 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008288#endif
8289#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008290 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008291#endif
Fred Drakec9680921999-12-13 16:37:25 +00008292#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008293 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008294#endif
8295#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008296 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008297#endif
8298#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008299 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008300#endif
8301#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008302 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008303#endif
8304#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008305 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008306#endif
8307#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008308 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008309#endif
8310#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008311 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008312#endif
8313#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008314 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008315#endif
8316#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008317 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008318#endif
8319#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008320 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008321#endif
8322#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008323 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008324#endif
8325#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008326 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008327#endif
8328#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008329 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008330#endif
8331#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008332 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008333#endif
8334#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008335 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008336#endif
8337#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008338 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008339#endif
8340#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008341 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008342#endif
8343#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008344 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008345#endif
8346#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008347 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008348#endif
8349#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008350 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008351#endif
8352#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008353 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008354#endif
8355#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008356 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008357#endif
8358#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008359 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008360#endif
8361#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008362 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008363#endif
8364#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008365 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008366#endif
8367#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008368 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008369#endif
8370#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008371 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008372#endif
8373#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008374 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008375#endif
8376#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008377 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008378#endif
8379#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008380 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008381#endif
8382#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008383 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008384#endif
8385#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008386 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008387#endif
8388#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008389 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008390#endif
8391#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008392 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008393#endif
8394#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008395 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008396#endif
Fred Draked86ed291999-12-15 15:34:33 +00008397#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008398 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008399#endif
Fred Drakec9680921999-12-13 16:37:25 +00008400#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008401 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008402#endif
8403#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008404 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008405#endif
8406#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008407 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008408#endif
8409#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008410 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008411#endif
8412#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008413 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008414#endif
8415#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008416 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008417#endif
8418#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008419 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008420#endif
8421#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008422 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008423#endif
8424#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008425 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008426#endif
8427#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008428 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008429#endif
8430#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008431 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008432#endif
8433#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008434 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008435#endif
8436#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008437 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008438#endif
8439#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008440 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008441#endif
8442#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008443 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008444#endif
8445#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008446 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008447#endif
8448#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008449 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008450#endif
8451#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008452 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008453#endif
8454#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008455 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008456#endif
8457#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008458 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008459#endif
8460#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008461 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008462#endif
8463#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008464 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008465#endif
8466#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008467 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008468#endif
8469#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008470 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008471#endif
8472#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008473 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008474#endif
8475#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008476 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008477#endif
8478#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008479 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008480#endif
8481#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008482 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008483#endif
8484#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008485 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008486#endif
8487#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008488 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008489#endif
8490#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008491 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008492#endif
8493#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008494 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008495#endif
8496#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008497 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008498#endif
8499#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008500 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008501#endif
8502#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008503 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008504#endif
8505#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008506 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008507#endif
8508#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008509 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008510#endif
8511#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008512 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008513#endif
8514#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008515 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008516#endif
8517#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008518 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008519#endif
8520#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008521 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008522#endif
8523#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008524 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008525#endif
8526#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008527 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008528#endif
8529#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008530 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008531#endif
8532#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008533 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008534#endif
8535};
8536
8537static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008538conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008539{
8540 return conv_confname(arg, valuep, posix_constants_sysconf,
8541 sizeof(posix_constants_sysconf)
8542 / sizeof(struct constdef));
8543}
8544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008545PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008546"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008547Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008548
8549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008550posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008551{
8552 PyObject *result = NULL;
8553 int name;
8554
8555 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008556 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008557
Victor Stinner862490a2010-05-06 00:03:44 +00008558 errno = 0;
8559 value = sysconf(name);
8560 if (value == -1 && errno != 0)
8561 posix_error();
8562 else
8563 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008564 }
8565 return result;
8566}
8567#endif
8568
8569
Fred Drakebec628d1999-12-15 18:31:10 +00008570/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008571 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008572 * the exported dictionaries that are used to publish information about the
8573 * names available on the host platform.
8574 *
8575 * Sorting the table at runtime ensures that the table is properly ordered
8576 * when used, even for platforms we're not able to test on. It also makes
8577 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008578 */
Fred Drakebec628d1999-12-15 18:31:10 +00008579
8580static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008581cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008582{
8583 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008584 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008585 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008586 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008587
8588 return strcmp(c1->name, c2->name);
8589}
8590
8591static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008592setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008593 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008594{
Fred Drakebec628d1999-12-15 18:31:10 +00008595 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008596 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008597 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8598 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008599 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008600 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008601
Barry Warsaw3155db32000-04-13 15:20:40 +00008602 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008603 PyObject *o = PyInt_FromLong(table[i].value);
8604 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8605 Py_XDECREF(o);
8606 Py_DECREF(d);
8607 return -1;
8608 }
8609 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008610 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008611 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008612}
8613
Fred Drakebec628d1999-12-15 18:31:10 +00008614/* Return -1 on failure, 0 on success. */
8615static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008616setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008617{
8618#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008619 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008620 sizeof(posix_constants_pathconf)
8621 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008622 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008623 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008624#endif
8625#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008626 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008627 sizeof(posix_constants_confstr)
8628 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008629 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008630 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008631#endif
8632#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008633 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008634 sizeof(posix_constants_sysconf)
8635 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008636 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008637 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008638#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008639 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008640}
Fred Draked86ed291999-12-15 15:34:33 +00008641
8642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008643PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008644"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008645Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008646in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008647
8648static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008649posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008650{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651 abort();
8652 /*NOTREACHED*/
8653 Py_FatalError("abort() called from Python code didn't abort!");
8654 return NULL;
8655}
Fred Drakebec628d1999-12-15 18:31:10 +00008656
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008657#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008658PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008659"startfile(filepath [, operation]) - Start a file with its associated\n\
8660application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008661\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008662When \"operation\" is not specified or \"open\", this acts like\n\
8663double-clicking the file in Explorer, or giving the file name as an\n\
8664argument to the DOS \"start\" command: the file is opened with whatever\n\
8665application (if any) its extension is associated.\n\
8666When another \"operation\" is given, it specifies what should be done with\n\
8667the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008668\n\
8669startfile returns as soon as the associated application is launched.\n\
8670There is no option to wait for the application to close, and no way\n\
8671to retrieve the application's exit status.\n\
8672\n\
8673The filepath is relative to the current directory. If you want to use\n\
8674an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008675the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008676
8677static PyObject *
8678win32_startfile(PyObject *self, PyObject *args)
8679{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008680 char *filepath;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008681 Py_UNICODE *wpath;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008682 char *operation = NULL;
8683 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008684
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008685 PyObject *woperation = NULL;
8686 if (!PyArg_ParseTuple(args, "u|s:startfile",
8687 &wpath, &operation)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008688 PyErr_Clear();
8689 goto normal;
8690 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008691
Victor Stinnerd6f85422010-05-05 23:33:33 +00008692 if (operation) {
8693 woperation = PyUnicode_DecodeASCII(operation,
8694 strlen(operation), NULL);
8695 if (!woperation) {
8696 PyErr_Clear();
8697 operation = NULL;
8698 goto normal;
8699 }
8700 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008701
Victor Stinnerd6f85422010-05-05 23:33:33 +00008702 Py_BEGIN_ALLOW_THREADS
8703 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008704 wpath,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008705 NULL, NULL, SW_SHOWNORMAL);
8706 Py_END_ALLOW_THREADS
8707
8708 Py_XDECREF(woperation);
8709 if (rc <= (HINSTANCE)32) {
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008710 PyObject *errval = win32_error_unicode("startfile", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00008711 return errval;
8712 }
8713 Py_INCREF(Py_None);
8714 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008715
8716normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008717 if (!PyArg_ParseTuple(args, "et|s:startfile",
8718 Py_FileSystemDefaultEncoding, &filepath,
8719 &operation))
8720 return NULL;
8721 Py_BEGIN_ALLOW_THREADS
8722 rc = ShellExecute((HWND)0, operation, filepath,
8723 NULL, NULL, SW_SHOWNORMAL);
8724 Py_END_ALLOW_THREADS
8725 if (rc <= (HINSTANCE)32) {
8726 PyObject *errval = win32_error("startfile", filepath);
8727 PyMem_Free(filepath);
8728 return errval;
8729 }
8730 PyMem_Free(filepath);
8731 Py_INCREF(Py_None);
8732 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008733}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008734#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008735
Martin v. Löwis438b5342002-12-27 10:16:42 +00008736#ifdef HAVE_GETLOADAVG
8737PyDoc_STRVAR(posix_getloadavg__doc__,
8738"getloadavg() -> (float, float, float)\n\n\
8739Return the number of processes in the system run queue averaged over\n\
8740the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8741was unobtainable");
8742
8743static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008744posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008745{
8746 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008747 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008748 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8749 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008750 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008751 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008752}
8753#endif
8754
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008755PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008756"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008757Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008758
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008759static PyObject *
8760posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008761{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008762 Py_ssize_t size;
8763 PyObject *result;
8764 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008765
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008766 /* Read arguments */
8767 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008768 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008769 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008770 return PyErr_Format(PyExc_ValueError,
8771 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008772 result = PyBytes_FromStringAndSize(NULL, size);
8773 if (result == NULL)
8774 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008775
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008776 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8777 PyBytes_GET_SIZE(result));
8778 if (ret == -1) {
8779 Py_DECREF(result);
8780 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008781 }
8782 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008783}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008784
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008785#ifdef HAVE_SETRESUID
8786PyDoc_STRVAR(posix_setresuid__doc__,
8787"setresuid(ruid, euid, suid)\n\n\
8788Set the current process's real, effective, and saved user ids.");
8789
8790static PyObject*
8791posix_setresuid (PyObject *self, PyObject *args)
8792{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008793 uid_t ruid, euid, suid;
8794 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8795 _Py_Uid_Converter, &ruid,
8796 _Py_Uid_Converter, &euid,
8797 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008798 return NULL;
8799 if (setresuid(ruid, euid, suid) < 0)
8800 return posix_error();
8801 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008802}
8803#endif
8804
8805#ifdef HAVE_SETRESGID
8806PyDoc_STRVAR(posix_setresgid__doc__,
8807"setresgid(rgid, egid, sgid)\n\n\
8808Set the current process's real, effective, and saved group ids.");
8809
8810static PyObject*
8811posix_setresgid (PyObject *self, PyObject *args)
8812{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008813 gid_t rgid, egid, sgid;
8814 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8815 _Py_Gid_Converter, &rgid,
8816 _Py_Gid_Converter, &egid,
8817 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008818 return NULL;
8819 if (setresgid(rgid, egid, sgid) < 0)
8820 return posix_error();
8821 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008822}
8823#endif
8824
8825#ifdef HAVE_GETRESUID
8826PyDoc_STRVAR(posix_getresuid__doc__,
8827"getresuid() -> (ruid, euid, suid)\n\n\
8828Get tuple of the current process's real, effective, and saved user ids.");
8829
8830static PyObject*
8831posix_getresuid (PyObject *self, PyObject *noargs)
8832{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008834 if (getresuid(&ruid, &euid, &suid) < 0)
8835 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008836 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8837 _PyInt_FromUid(euid),
8838 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008839}
8840#endif
8841
8842#ifdef HAVE_GETRESGID
8843PyDoc_STRVAR(posix_getresgid__doc__,
8844"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008845Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008846
8847static PyObject*
8848posix_getresgid (PyObject *self, PyObject *noargs)
8849{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008850 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 if (getresgid(&rgid, &egid, &sgid) < 0)
8852 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008853 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8854 _PyInt_FromGid(egid),
8855 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008856}
8857#endif
8858
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008859static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008860 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008861#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008862 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008863#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008864 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008865#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008866 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008867#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008869#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008870 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008871#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008872#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008873 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008874#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008875#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008876 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008877#endif /* HAVE_LCHMOD */
8878#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008879 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008880#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008881#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008883#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008884#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008885 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008886#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008887#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008888 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008889#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008890#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008891 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008892#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008893#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008894 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008895#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008896 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008897#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008898#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008899#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008900 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008901#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008902 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8903 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8904 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008905#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008906 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008907#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008908#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008909 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008910#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008911 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8912 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8913 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8914 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008915#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008916 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008917#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008918#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008919 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008920#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008921 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008922#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008923 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008924#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008925 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8926 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8927 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008928#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008930#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008931 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008932#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008933 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8934 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008935#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008936#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008937 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8938 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008939#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008940 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8941 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008942#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008943#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008944#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008945 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008946#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008947#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008949#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008950#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008951 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008952#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008953#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008954 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008955#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008956#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008957 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008958#endif /* HAVE_GETEGID */
8959#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008960 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008961#endif /* HAVE_GETEUID */
8962#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008964#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008965#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008966 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008967#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008968 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008969#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008970 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008971#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008972#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008973 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008974#endif /* HAVE_GETPPID */
8975#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008976 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008977#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008978#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008979 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008980#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008981#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008982 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008983#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008984#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008985 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008986#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008987#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008988 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008989#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008990#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008991 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008992#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008993 {"popen2", win32_popen2, METH_VARARGS},
8994 {"popen3", win32_popen3, METH_VARARGS},
8995 {"popen4", win32_popen4, METH_VARARGS},
8996 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8997 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008998#else
8999#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009000 {"popen2", os2emx_popen2, METH_VARARGS},
9001 {"popen3", os2emx_popen3, METH_VARARGS},
9002 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009003#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00009004#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009005#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009006#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009007 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009008#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009009#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009010 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009011#endif /* HAVE_SETEUID */
9012#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009013 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009014#endif /* HAVE_SETEGID */
9015#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009016 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009017#endif /* HAVE_SETREUID */
9018#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009019 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009020#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009021#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009022 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009023#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009024#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009025 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009026#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009027#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009028 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009029#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00009030#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009031 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00009032#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009033#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009034 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009035#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009036#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009038#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009039#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009040 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009041#endif /* HAVE_WAIT3 */
9042#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009043 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009044#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009045#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009046 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009047#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009048#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009049 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009050#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009051#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009052 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009053#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009054#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009055 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009056#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009057#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009059#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009060#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009061 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009062#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009063 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009064 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9066 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9067 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9068 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9069 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9070 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9071 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9072 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9073 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009074#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009075 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009076#endif
9077#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009078 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009079#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009080#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009081 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009082#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009083#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009084 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9085 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9086 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009087#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009088#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009090#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009091#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009092 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009093#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009094#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009095 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009096#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009098#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009099 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009100#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009101#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009102 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009103#endif
9104#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009105 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009106#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009107#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009108#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009109 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009110#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009111#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009112 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009113#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009114#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009115 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009116#endif /* WIFSTOPPED */
9117#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009119#endif /* WIFSIGNALED */
9120#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009122#endif /* WIFEXITED */
9123#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009124 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009125#endif /* WEXITSTATUS */
9126#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009127 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009128#endif /* WTERMSIG */
9129#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009131#endif /* WSTOPSIG */
9132#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009133#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009134 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009135#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009136#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009137 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009138#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009139#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009140 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009141#endif
9142#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009143 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009144#endif
9145#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009146 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009147#endif
Fred Drakec9680921999-12-13 16:37:25 +00009148#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009149 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009150#endif
9151#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009152 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009153#endif
9154#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009155 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009156#endif
9157#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009158 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009159#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009160 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009161#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009162 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009163 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009164#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009165#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009166 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009167#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009168#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009169 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009170#endif
9171#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009172 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009173#endif
9174#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009175 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009176#endif
9177#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009178 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009179#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009180 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009181 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009182};
9183
9184
Barry Warsaw4a342091996-12-19 23:50:02 +00009185static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009186ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009187{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009188 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009189}
9190
Guido van Rossumd48f2521997-12-05 22:19:34 +00009191#if defined(PYOS_OS2)
9192/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009193static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009194{
9195 APIRET rc;
9196 ULONG values[QSV_MAX+1];
9197 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009198 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009199
9200 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009201 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009202 Py_END_ALLOW_THREADS
9203
9204 if (rc != NO_ERROR) {
9205 os2_error(rc);
9206 return -1;
9207 }
9208
Fred Drake4d1e64b2002-04-15 19:40:07 +00009209 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9210 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9211 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9212 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9213 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9214 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9215 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009216
9217 switch (values[QSV_VERSION_MINOR]) {
9218 case 0: ver = "2.00"; break;
9219 case 10: ver = "2.10"; break;
9220 case 11: ver = "2.11"; break;
9221 case 30: ver = "3.00"; break;
9222 case 40: ver = "4.00"; break;
9223 case 50: ver = "5.00"; break;
9224 default:
Tim Peters885d4572001-11-28 20:27:42 +00009225 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009226 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009227 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009228 ver = &tmp[0];
9229 }
9230
9231 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009232 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009233 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009234
9235 /* Add Indicator of Which Drive was Used to Boot the System */
9236 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9237 tmp[1] = ':';
9238 tmp[2] = '\0';
9239
Fred Drake4d1e64b2002-04-15 19:40:07 +00009240 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009241}
9242#endif
9243
Barry Warsaw4a342091996-12-19 23:50:02 +00009244static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009245all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009246{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009247#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009248 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009249#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009250#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009251 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009252#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009253#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009254 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009255#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009256#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009257 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009258#endif
Fred Drakec9680921999-12-13 16:37:25 +00009259#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009260 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009261#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009262#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009263 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009264#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009265#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009266 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009267#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009268#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009269 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009270#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009271#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009272 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009273#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009274#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009275 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009276#endif
9277#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009278 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009279#endif
9280#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009281 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009282#endif
9283#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009284 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009285#endif
9286#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009287 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009288#endif
9289#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009290 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009291#endif
9292#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009293 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009294#endif
9295#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009296 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009297#endif
9298#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009299 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009300#endif
9301#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009302 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009303#endif
9304#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009305 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009306#endif
9307#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009308 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009309#endif
9310#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009311 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009312#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009313#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009314 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009315#endif
9316#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009317 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009318#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009319#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009320 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009321#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009322#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009323 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009324#endif
9325#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009326 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009327#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009328
Tim Peters5aa91602002-01-30 05:46:57 +00009329/* MS Windows */
9330#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009331 /* Don't inherit in child processes. */
9332 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009333#endif
9334#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009335 /* Optimize for short life (keep in memory). */
9336 /* MS forgot to define this one with a non-underscore form too. */
9337 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009338#endif
9339#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009340 /* Automatically delete when last handle is closed. */
9341 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009342#endif
9343#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009344 /* Optimize for random access. */
9345 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009346#endif
9347#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009348 /* Optimize for sequential access. */
9349 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009350#endif
9351
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009352/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009353#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009354 /* Send a SIGIO signal whenever input or output
9355 becomes available on file descriptor */
9356 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009357#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009358#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009359 /* Direct disk access. */
9360 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009361#endif
9362#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009363 /* Must be a directory. */
9364 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009365#endif
9366#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009367 /* Do not follow links. */
9368 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009369#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009370#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009371 /* Do not update the access time. */
9372 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009373#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009374
Victor Stinnerd6f85422010-05-05 23:33:33 +00009375 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009376#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009377 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009378#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009379#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009380 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009381#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009382#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009383 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009384#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009385#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009386 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009387#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009388#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009389 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009390#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009391#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009392 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009393#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009394#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009395 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009396#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009397#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009398 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009399#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009400#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009401 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009402#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009403#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009404 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009405#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009406#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009407 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009408#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009409#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009410 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009411#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009412#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009413 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009414#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009415#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009416 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009417#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009418#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009419 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009420#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009421#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009422 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009423#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009424#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009425 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009426#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009427
Guido van Rossum246bc171999-02-01 23:54:31 +00009428#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009429#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009430 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9431 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9432 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9433 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9434 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9435 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9436 if (ins(d, "P_PM", (long)P_PM)) return -1;
9437 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9438 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9439 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9440 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9441 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9442 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9443 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9444 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9445 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9446 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9447 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9448 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9449 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009450#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009451 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9452 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9453 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9454 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9455 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009456#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009457#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009458
Guido van Rossumd48f2521997-12-05 22:19:34 +00009459#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009460 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009461#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009462 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009463}
9464
9465
Tim Peters5aa91602002-01-30 05:46:57 +00009466#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009467#define INITFUNC initnt
9468#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009469
9470#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009471#define INITFUNC initos2
9472#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009473
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009474#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009475#define INITFUNC initposix
9476#define MODNAME "posix"
9477#endif
9478
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009479PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009480INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009481{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009482 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009483
Victor Stinnerd6f85422010-05-05 23:33:33 +00009484 m = Py_InitModule3(MODNAME,
9485 posix_methods,
9486 posix__doc__);
9487 if (m == NULL)
9488 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009489
Victor Stinnerd6f85422010-05-05 23:33:33 +00009490 /* Initialize environ dictionary */
9491 v = convertenviron();
9492 Py_XINCREF(v);
9493 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9494 return;
9495 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009496
Victor Stinnerd6f85422010-05-05 23:33:33 +00009497 if (all_ins(m))
9498 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009499
Victor Stinnerd6f85422010-05-05 23:33:33 +00009500 if (setup_confname_tables(m))
9501 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009502
Victor Stinnerd6f85422010-05-05 23:33:33 +00009503 Py_INCREF(PyExc_OSError);
9504 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009505
Guido van Rossumb3d39562000-01-31 18:41:26 +00009506#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009507 if (posix_putenv_garbage == NULL)
9508 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009509#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009510
Victor Stinnerd6f85422010-05-05 23:33:33 +00009511 if (!initialized) {
9512 stat_result_desc.name = MODNAME ".stat_result";
9513 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9514 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9515 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9516 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9517 structseq_new = StatResultType.tp_new;
9518 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009519
Victor Stinnerd6f85422010-05-05 23:33:33 +00009520 statvfs_result_desc.name = MODNAME ".statvfs_result";
9521 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009522#ifdef NEED_TICKS_PER_SECOND
9523# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009524 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009525# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009526 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009527# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009528 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009529# endif
9530#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009531 }
9532 Py_INCREF((PyObject*) &StatResultType);
9533 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9534 Py_INCREF((PyObject*) &StatVFSResultType);
9535 PyModule_AddObject(m, "statvfs_result",
9536 (PyObject*) &StatVFSResultType);
9537 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009538
9539#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009540 /*
9541 * Step 2 of weak-linking support on Mac OS X.
9542 *
9543 * The code below removes functions that are not available on the
9544 * currently active platform.
9545 *
9546 * This block allow one to use a python binary that was build on
9547 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9548 * OSX 10.4.
9549 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009550#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009551 if (fstatvfs == NULL) {
9552 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9553 return;
9554 }
9555 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009556#endif /* HAVE_FSTATVFS */
9557
9558#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009559 if (statvfs == NULL) {
9560 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9561 return;
9562 }
9563 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009564#endif /* HAVE_STATVFS */
9565
9566# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009567 if (lchown == NULL) {
9568 if (PyObject_DelAttrString(m, "lchown") == -1) {
9569 return;
9570 }
9571 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009572#endif /* HAVE_LCHOWN */
9573
9574
9575#endif /* __APPLE__ */
9576
Guido van Rossumb6775db1994-08-01 11:34:53 +00009577}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009578
9579#ifdef __cplusplus
9580}
9581#endif
9582
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009583