blob: 7a1a6945c102eb19988bd946e445ddae689e98b3 [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:";
Alexey Izbyshevaa40f922018-03-01 13:27:34 +0300987 int is_unc_like_path;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000988
Victor Stinnerd6f85422010-05-05 23:33:33 +0000989 if(!SetCurrentDirectoryW(path))
990 return FALSE;
991 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
992 if (!result)
993 return FALSE;
994 if (result > MAX_PATH+1) {
995 new_path = malloc(result * sizeof(wchar_t));
996 if (!new_path) {
997 SetLastError(ERROR_OUTOFMEMORY);
998 return FALSE;
999 }
1000 result = GetCurrentDirectoryW(result, new_path);
1001 if (!result) {
1002 free(new_path);
1003 return FALSE;
1004 }
1005 }
Alexey Izbyshevaa40f922018-03-01 13:27:34 +03001006 is_unc_like_path = (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1007 wcsncmp(new_path, L"//", 2) == 0);
1008 if (!is_unc_like_path) {
1009 env[1] = new_path[0];
1010 result = SetEnvironmentVariableW(env, new_path);
1011 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00001012 if (new_path != _new_path)
1013 free(new_path);
Alexey Izbyshevaa40f922018-03-01 13:27:34 +03001014 return result ? TRUE : FALSE;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001015}
1016#endif
1017
Antoine Pitrouff48c0a2011-07-01 22:56:03 +02001018/* choose the appropriate stat and fstat functions and return structs */
1019#undef STAT
1020#undef FSTAT
1021#undef STRUCT_STAT
1022#if defined(MS_WIN64) || defined(MS_WINDOWS)
1023# define STAT win32_stat
1024# define FSTAT win32_fstat
1025# define STRUCT_STAT struct win32_stat
1026#else
1027# define STAT stat
1028# define FSTAT fstat
1029# define STRUCT_STAT struct stat
1030#endif
1031
Martin v. Löwis14694662006-02-03 12:54:16 +00001032#ifdef MS_WINDOWS
1033/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1034 - time stamps are restricted to second resolution
1035 - file modification times suffer from forth-and-back conversions between
1036 UTC and local time
1037 Therefore, we implement our own stat, based on the Win32 API directly.
1038*/
Victor Stinnerd6f85422010-05-05 23:33:33 +00001039#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001040
1041struct win32_stat{
1042 int st_dev;
1043 __int64 st_ino;
1044 unsigned short st_mode;
1045 int st_nlink;
1046 int st_uid;
1047 int st_gid;
1048 int st_rdev;
1049 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001050 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001051 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001052 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001053 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001054 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +00001055 int st_ctime_nsec;
1056};
1057
1058static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
1059
1060static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001061FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +00001062{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001063 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
1064 /* Cannot simply cast and dereference in_ptr,
1065 since it might not be aligned properly */
1066 __int64 in;
1067 memcpy(&in, in_ptr, sizeof(in));
1068 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001069 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +00001070}
1071
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001072static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00001073time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001074{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001075 /* XXX endianness */
1076 __int64 out;
1077 out = time_in + secs_between_epochs;
1078 out = out * 10000000 + nsec_in / 100;
1079 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001080}
1081
Martin v. Löwis14694662006-02-03 12:54:16 +00001082/* Below, we *know* that ugo+r is 0444 */
1083#if _S_IREAD != 0400
1084#error Unsupported C library
1085#endif
1086static int
1087attributes_to_mode(DWORD attr)
1088{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001089 int m = 0;
1090 if (attr & FILE_ATTRIBUTE_DIRECTORY)
1091 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
1092 else
1093 m |= _S_IFREG;
1094 if (attr & FILE_ATTRIBUTE_READONLY)
1095 m |= 0444;
1096 else
1097 m |= 0666;
1098 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +00001099}
1100
1101static int
1102attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
1103{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001104 memset(result, 0, sizeof(*result));
1105 result->st_mode = attributes_to_mode(info->dwFileAttributes);
1106 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
1107 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1108 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1109 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +00001110
Victor Stinnerd6f85422010-05-05 23:33:33 +00001111 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001112}
1113
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001114static BOOL
1115attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1116{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001117 HANDLE hFindFile;
1118 WIN32_FIND_DATAA FileData;
1119 hFindFile = FindFirstFileA(pszFile, &FileData);
1120 if (hFindFile == INVALID_HANDLE_VALUE)
1121 return FALSE;
1122 FindClose(hFindFile);
1123 pfad->dwFileAttributes = FileData.dwFileAttributes;
1124 pfad->ftCreationTime = FileData.ftCreationTime;
1125 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1126 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1127 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1128 pfad->nFileSizeLow = FileData.nFileSizeLow;
1129 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001130}
1131
1132static BOOL
1133attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
1134{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001135 HANDLE hFindFile;
1136 WIN32_FIND_DATAW FileData;
1137 hFindFile = FindFirstFileW(pszFile, &FileData);
1138 if (hFindFile == INVALID_HANDLE_VALUE)
1139 return FALSE;
1140 FindClose(hFindFile);
1141 pfad->dwFileAttributes = FileData.dwFileAttributes;
1142 pfad->ftCreationTime = FileData.ftCreationTime;
1143 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
1144 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
1145 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
1146 pfad->nFileSizeLow = FileData.nFileSizeLow;
1147 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +00001148}
1149
Victor Stinnerd6f85422010-05-05 23:33:33 +00001150static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001151win32_stat(const char* path, struct win32_stat *result)
1152{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001153 WIN32_FILE_ATTRIBUTE_DATA info;
1154 int code;
1155 char *dot;
1156 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
1157 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1158 /* Protocol violation: we explicitly clear errno, instead of
1159 setting it to a POSIX error. Callers should use GetLastError. */
1160 errno = 0;
1161 return -1;
1162 } else {
1163 /* Could not get attributes on open file. Fall back to
1164 reading the directory. */
1165 if (!attributes_from_dir(path, &info)) {
1166 /* Very strange. This should not fail now */
1167 errno = 0;
1168 return -1;
1169 }
1170 }
1171 }
1172 code = attribute_data_to_stat(&info, result);
1173 if (code != 0)
1174 return code;
1175 /* Set S_IFEXEC if it is an .exe, .bat, ... */
1176 dot = strrchr(path, '.');
1177 if (dot) {
1178 if (stricmp(dot, ".bat") == 0 ||
1179 stricmp(dot, ".cmd") == 0 ||
1180 stricmp(dot, ".exe") == 0 ||
1181 stricmp(dot, ".com") == 0)
1182 result->st_mode |= 0111;
1183 }
1184 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001185}
1186
Victor Stinnerd6f85422010-05-05 23:33:33 +00001187static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001188win32_wstat(const wchar_t* path, struct win32_stat *result)
1189{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001190 int code;
1191 const wchar_t *dot;
1192 WIN32_FILE_ATTRIBUTE_DATA info;
1193 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1194 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1195 /* Protocol violation: we explicitly clear errno, instead of
1196 setting it to a POSIX error. Callers should use GetLastError. */
1197 errno = 0;
1198 return -1;
1199 } else {
1200 /* Could not get attributes on open file. Fall back to
1201 reading the directory. */
1202 if (!attributes_from_dir_w(path, &info)) {
1203 /* Very strange. This should not fail now */
1204 errno = 0;
1205 return -1;
1206 }
1207 }
1208 }
1209 code = attribute_data_to_stat(&info, result);
1210 if (code < 0)
1211 return code;
1212 /* Set IFEXEC if it is an .exe, .bat, ... */
1213 dot = wcsrchr(path, '.');
1214 if (dot) {
1215 if (_wcsicmp(dot, L".bat") == 0 ||
1216 _wcsicmp(dot, L".cmd") == 0 ||
1217 _wcsicmp(dot, L".exe") == 0 ||
1218 _wcsicmp(dot, L".com") == 0)
1219 result->st_mode |= 0111;
1220 }
1221 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001222}
1223
1224static int
1225win32_fstat(int file_number, struct win32_stat *result)
1226{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001227 BY_HANDLE_FILE_INFORMATION info;
1228 HANDLE h;
1229 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001230
Victor Stinnerd6f85422010-05-05 23:33:33 +00001231 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001232
Victor Stinnerd6f85422010-05-05 23:33:33 +00001233 /* Protocol violation: we explicitly clear errno, instead of
1234 setting it to a POSIX error. Callers should use GetLastError. */
1235 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001236
Victor Stinnerd6f85422010-05-05 23:33:33 +00001237 if (h == INVALID_HANDLE_VALUE) {
1238 /* This is really a C library error (invalid file handle).
1239 We set the Win32 error to the closes one matching. */
1240 SetLastError(ERROR_INVALID_HANDLE);
1241 return -1;
1242 }
1243 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001244
Victor Stinnerd6f85422010-05-05 23:33:33 +00001245 type = GetFileType(h);
1246 if (type == FILE_TYPE_UNKNOWN) {
1247 DWORD error = GetLastError();
1248 if (error != 0) {
1249 return -1;
1250 }
1251 /* else: valid but unknown file */
1252 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001253
Victor Stinnerd6f85422010-05-05 23:33:33 +00001254 if (type != FILE_TYPE_DISK) {
1255 if (type == FILE_TYPE_CHAR)
1256 result->st_mode = _S_IFCHR;
1257 else if (type == FILE_TYPE_PIPE)
1258 result->st_mode = _S_IFIFO;
1259 return 0;
1260 }
1261
1262 if (!GetFileInformationByHandle(h, &info)) {
1263 return -1;
1264 }
1265
1266 /* similar to stat() */
1267 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1268 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1269 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1270 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1271 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1272 /* specific to fstat() */
1273 result->st_nlink = info.nNumberOfLinks;
1274 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1275 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001276}
1277
1278#endif /* MS_WINDOWS */
1279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001280PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001281"stat_result: Result from stat or lstat.\n\n\
1282This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001283 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001284or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1285\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001286Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1287or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001288\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001289See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001290
1291static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001292 {"st_mode", "protection bits"},
1293 {"st_ino", "inode"},
1294 {"st_dev", "device"},
1295 {"st_nlink", "number of hard links"},
1296 {"st_uid", "user ID of owner"},
1297 {"st_gid", "group ID of owner"},
1298 {"st_size", "total size, in bytes"},
1299 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1300 {NULL, "integer time of last access"},
1301 {NULL, "integer time of last modification"},
1302 {NULL, "integer time of last change"},
1303 {"st_atime", "time of last access"},
1304 {"st_mtime", "time of last modification"},
1305 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001306#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001308#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001309#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001310 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001311#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001312#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001313 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001314#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001315#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001316 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001317#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001318#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001319 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001320#endif
1321#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001322 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001323#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001324 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001325};
1326
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001327#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001328#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001329#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001330#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331#endif
1332
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001333#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001334#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1335#else
1336#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1337#endif
1338
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001339#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1341#else
1342#define ST_RDEV_IDX ST_BLOCKS_IDX
1343#endif
1344
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001345#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1346#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1347#else
1348#define ST_FLAGS_IDX ST_RDEV_IDX
1349#endif
1350
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001351#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001352#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001353#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001354#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001355#endif
1356
1357#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1358#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1359#else
1360#define ST_BIRTHTIME_IDX ST_GEN_IDX
1361#endif
1362
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001363static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001364 "stat_result", /* name */
1365 stat_result__doc__, /* doc */
1366 stat_result_fields,
1367 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001368};
1369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001371"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1372This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001373 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001374or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001375\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001376See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001377
1378static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001379 {"f_bsize", },
1380 {"f_frsize", },
1381 {"f_blocks", },
1382 {"f_bfree", },
1383 {"f_bavail", },
1384 {"f_files", },
1385 {"f_ffree", },
1386 {"f_favail", },
1387 {"f_flag", },
1388 {"f_namemax",},
1389 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001390};
1391
1392static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001393 "statvfs_result", /* name */
1394 statvfs_result__doc__, /* doc */
1395 statvfs_result_fields,
1396 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001397};
1398
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001399static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001400static PyTypeObject StatResultType;
1401static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001402static newfunc structseq_new;
1403
1404static PyObject *
1405statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1406{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001407 PyStructSequence *result;
1408 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001409
Victor Stinnerd6f85422010-05-05 23:33:33 +00001410 result = (PyStructSequence*)structseq_new(type, args, kwds);
1411 if (!result)
1412 return NULL;
1413 /* If we have been initialized from a tuple,
1414 st_?time might be set to None. Initialize it
1415 from the int slots. */
1416 for (i = 7; i <= 9; i++) {
1417 if (result->ob_item[i+3] == Py_None) {
1418 Py_DECREF(Py_None);
1419 Py_INCREF(result->ob_item[i]);
1420 result->ob_item[i+3] = result->ob_item[i];
1421 }
1422 }
1423 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001424}
1425
1426
1427
1428/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001429static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001430
1431PyDoc_STRVAR(stat_float_times__doc__,
1432"stat_float_times([newval]) -> oldval\n\n\
1433Determine whether os.[lf]stat represents time stamps as float objects.\n\
1434If newval is True, future calls to stat() return floats, if it is False,\n\
1435future calls return ints. \n\
1436If newval is omitted, return the current setting.\n");
1437
1438static PyObject*
1439stat_float_times(PyObject* self, PyObject *args)
1440{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001441 int newval = -1;
1442 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1443 return NULL;
1444 if (newval == -1)
1445 /* Return old value */
1446 return PyBool_FromLong(_stat_float_times);
1447 _stat_float_times = newval;
1448 Py_INCREF(Py_None);
1449 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001450}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001451
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001452static void
1453fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1454{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001455 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001456#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001457 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001458#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001459 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001460#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001461 if (!ival)
1462 return;
1463 if (_stat_float_times) {
1464 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1465 } else {
1466 fval = ival;
1467 Py_INCREF(fval);
1468 }
1469 PyStructSequence_SET_ITEM(v, index, ival);
1470 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001471}
1472
Tim Peters5aa91602002-01-30 05:46:57 +00001473/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001474 (used by posix_stat() and posix_fstat()) */
1475static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001476_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001477{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001478 unsigned long ansec, mnsec, cnsec;
1479 PyObject *v = PyStructSequence_New(&StatResultType);
1480 if (v == NULL)
1481 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001482
Victor Stinnerd6f85422010-05-05 23:33:33 +00001483 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001484#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001485 PyStructSequence_SET_ITEM(v, 1,
1486 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001487#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001488 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001489#endif
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001490#ifdef MS_WINDOWS
1491 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001492#else
Serhiy Storchaka2098d612015-01-18 11:11:25 +02001493 PyStructSequence_SET_ITEM(v, 2, _PyInt_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001494#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001495 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02001496#if defined(MS_WINDOWS)
1497 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong(0));
1498 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong(0));
1499#else
1500 PyStructSequence_SET_ITEM(v, 4, _PyInt_FromUid(st->st_uid));
1501 PyStructSequence_SET_ITEM(v, 5, _PyInt_FromGid(st->st_gid));
1502#endif
Fred Drake699f3522000-06-29 21:12:41 +00001503#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001504 PyStructSequence_SET_ITEM(v, 6,
1505 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001506#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001507 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001508#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001509
Martin v. Löwis14694662006-02-03 12:54:16 +00001510#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001511 ansec = st->st_atim.tv_nsec;
1512 mnsec = st->st_mtim.tv_nsec;
1513 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001514#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001515 ansec = st->st_atimespec.tv_nsec;
1516 mnsec = st->st_mtimespec.tv_nsec;
1517 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001518#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001519 ansec = st->st_atime_nsec;
1520 mnsec = st->st_mtime_nsec;
1521 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001522#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001523 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001524#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001525 fill_time(v, 7, st->st_atime, ansec);
1526 fill_time(v, 8, st->st_mtime, mnsec);
1527 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001528
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001529#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001530 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1531 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001532#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001533#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001534 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1535 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001536#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001537#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001538 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1539 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001540#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001541#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001542 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1543 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001544#endif
1545#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001546 {
1547 PyObject *val;
1548 unsigned long bsec,bnsec;
1549 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001550#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001551 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001552#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001553 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001554#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001555 if (_stat_float_times) {
1556 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1557 } else {
1558 val = PyInt_FromLong((long)bsec);
1559 }
1560 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1561 val);
1562 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001563#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001564#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001565 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1566 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001567#endif
Fred Drake699f3522000-06-29 21:12:41 +00001568
Victor Stinnerd6f85422010-05-05 23:33:33 +00001569 if (PyErr_Occurred()) {
1570 Py_DECREF(v);
1571 return NULL;
1572 }
Fred Drake699f3522000-06-29 21:12:41 +00001573
Victor Stinnerd6f85422010-05-05 23:33:33 +00001574 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001575}
1576
Martin v. Löwisd8948722004-06-02 09:57:56 +00001577#ifdef MS_WINDOWS
1578
1579/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1580 where / can be used in place of \ and the trailing slash is optional.
1581 Both SERVER and SHARE must have at least one character.
1582*/
1583
1584#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1585#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001586#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001587#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001588#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001589
Tim Peters4ad82172004-08-30 17:02:04 +00001590static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001591IsUNCRootA(char *path, int pathlen)
1592{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001593 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001594
Victor Stinnerd6f85422010-05-05 23:33:33 +00001595 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001596
Victor Stinnerd6f85422010-05-05 23:33:33 +00001597 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1598 /* minimum UNCRoot is \\x\y */
1599 return FALSE;
1600 for (i = 2; i < pathlen ; i++)
1601 if (ISSLASH(path[i])) break;
1602 if (i == 2 || i == pathlen)
1603 /* do not allow \\\SHARE or \\SERVER */
1604 return FALSE;
1605 share = i+1;
1606 for (i = share; i < pathlen; i++)
1607 if (ISSLASH(path[i])) break;
1608 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001609
Victor Stinnerd6f85422010-05-05 23:33:33 +00001610 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001611}
1612
Tim Peters4ad82172004-08-30 17:02:04 +00001613static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001614IsUNCRootW(Py_UNICODE *path, int pathlen)
1615{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001616 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001617
Victor Stinnerd6f85422010-05-05 23:33:33 +00001618 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001619
Victor Stinnerd6f85422010-05-05 23:33:33 +00001620 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1621 /* minimum UNCRoot is \\x\y */
1622 return FALSE;
1623 for (i = 2; i < pathlen ; i++)
1624 if (ISSLASH(path[i])) break;
1625 if (i == 2 || i == pathlen)
1626 /* do not allow \\\SHARE or \\SERVER */
1627 return FALSE;
1628 share = i+1;
1629 for (i = share; i < pathlen; i++)
1630 if (ISSLASH(path[i])) break;
1631 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001632
Victor Stinnerd6f85422010-05-05 23:33:33 +00001633 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001634}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001635#endif /* MS_WINDOWS */
1636
Barry Warsaw53699e91996-12-10 23:23:01 +00001637static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001638posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001639 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001640#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001641 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001642#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001643 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001644#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001645 char *wformat,
1646 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001648 STRUCT_STAT st;
1649 char *path = NULL; /* pass this to stat; do not free() it */
1650 char *pathfree = NULL; /* this memory must be free'd */
1651 int res;
1652 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001653
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001654#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001655 Py_UNICODE *wpath;
1656 if (PyArg_ParseTuple(args, wformat, &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001657 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001658 res = wstatfunc(wpath, &st);
1659 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001660
Victor Stinnerd6f85422010-05-05 23:33:33 +00001661 if (res != 0)
1662 return win32_error_unicode("stat", wpath);
1663 return _pystat_fromstructstat(&st);
1664 }
1665 /* Drop the argument parsing error as narrow strings
1666 are also valid. */
1667 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001668#endif
1669
Victor Stinnerd6f85422010-05-05 23:33:33 +00001670 if (!PyArg_ParseTuple(args, format,
1671 Py_FileSystemDefaultEncoding, &path))
1672 return NULL;
1673 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001674
Victor Stinnerd6f85422010-05-05 23:33:33 +00001675 Py_BEGIN_ALLOW_THREADS
1676 res = (*statfunc)(path, &st);
1677 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001678
Victor Stinnerd6f85422010-05-05 23:33:33 +00001679 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001680#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001681 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001682#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001683 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001684#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001685 }
1686 else
1687 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001688
Victor Stinnerd6f85422010-05-05 23:33:33 +00001689 PyMem_Free(pathfree);
1690 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691}
1692
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693/* POSIX methods */
1694
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001695PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001696"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001697Use the real uid/gid to test for access to a path. Note that most\n\
1698operations will use the effective uid/gid, therefore this routine can\n\
1699be used in a suid/sgid environment to test if the invoking user has the\n\
1700specified access to the path. The mode argument can be F_OK to test\n\
1701existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001702
1703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001704posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001705{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001706 char *path;
1707 int mode;
1708
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001709#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001710 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001711 Py_UNICODE *wpath;
1712 if (PyArg_ParseTuple(args, "ui:access", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001713 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001714 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001715 Py_END_ALLOW_THREADS
1716 goto finish;
1717 }
1718 /* Drop the argument parsing error as narrow strings
1719 are also valid. */
1720 PyErr_Clear();
1721 if (!PyArg_ParseTuple(args, "eti:access",
1722 Py_FileSystemDefaultEncoding, &path, &mode))
1723 return NULL;
1724 Py_BEGIN_ALLOW_THREADS
1725 attr = GetFileAttributesA(path);
1726 Py_END_ALLOW_THREADS
1727 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001728finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001729 if (attr == 0xFFFFFFFF)
1730 /* File does not exist, or cannot read attributes */
1731 return PyBool_FromLong(0);
1732 /* Access is possible if either write access wasn't requested, or
1733 the file isn't read-only, or if it's a directory, as there are
1734 no read-only directories on Windows. */
1735 return PyBool_FromLong(!(mode & 2)
1736 || !(attr & FILE_ATTRIBUTE_READONLY)
1737 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001738#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001739 int res;
1740 if (!PyArg_ParseTuple(args, "eti:access",
1741 Py_FileSystemDefaultEncoding, &path, &mode))
1742 return NULL;
1743 Py_BEGIN_ALLOW_THREADS
1744 res = access(path, mode);
1745 Py_END_ALLOW_THREADS
1746 PyMem_Free(path);
1747 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001748#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001749}
1750
Guido van Rossumd371ff11999-01-25 16:12:23 +00001751#ifndef F_OK
1752#define F_OK 0
1753#endif
1754#ifndef R_OK
1755#define R_OK 4
1756#endif
1757#ifndef W_OK
1758#define W_OK 2
1759#endif
1760#ifndef X_OK
1761#define X_OK 1
1762#endif
1763
1764#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001768
1769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001770posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001771{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001772 int id;
1773 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001774
Victor Stinnerd6f85422010-05-05 23:33:33 +00001775 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1776 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001777
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001778#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001779 /* file descriptor 0 only, the default input device (stdin) */
1780 if (id == 0) {
1781 ret = ttyname();
1782 }
1783 else {
1784 ret = NULL;
1785 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001786#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001787 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001788#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001789 if (ret == NULL)
1790 return posix_error();
1791 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001792}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001793#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001794
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001795#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001796PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001797"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001798Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001799
1800static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001801posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001803 char *ret;
1804 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001805
Greg Wardb48bc172000-03-01 21:51:56 +00001806#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001807 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001809 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001810#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001811 if (ret == NULL)
1812 return posix_error();
1813 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001814}
1815#endif
1816
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001817PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001818"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001819Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001820
Barry Warsaw53699e91996-12-10 23:23:01 +00001821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001823{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001824#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001825 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001826#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001827 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001828#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001829 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001830#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001831 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001832#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833}
1834
Fred Drake4d1e64b2002-04-15 19:40:07 +00001835#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001838Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001840
1841static PyObject *
1842posix_fchdir(PyObject *self, PyObject *fdobj)
1843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001844 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001845}
1846#endif /* HAVE_FCHDIR */
1847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001848
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001850"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001852
Barry Warsaw53699e91996-12-10 23:23:01 +00001853static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001854posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001856 char *path = NULL;
1857 int i;
1858 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001859#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001860 DWORD attr;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001861 Py_UNICODE *wpath;
1862 if (PyArg_ParseTuple(args, "ui|:chmod", &wpath, &i)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001863 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001864 attr = GetFileAttributesW(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001865 if (attr != 0xFFFFFFFF) {
1866 if (i & _S_IWRITE)
1867 attr &= ~FILE_ATTRIBUTE_READONLY;
1868 else
1869 attr |= FILE_ATTRIBUTE_READONLY;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001870 res = SetFileAttributesW(wpath, attr);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001871 }
1872 else
1873 res = 0;
1874 Py_END_ALLOW_THREADS
1875 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03001876 return win32_error_unicode("chmod", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00001877 Py_INCREF(Py_None);
1878 return Py_None;
1879 }
1880 /* Drop the argument parsing error as narrow strings
1881 are also valid. */
1882 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001883
Victor Stinnerd6f85422010-05-05 23:33:33 +00001884 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1885 &path, &i))
1886 return NULL;
1887 Py_BEGIN_ALLOW_THREADS
1888 attr = GetFileAttributesA(path);
1889 if (attr != 0xFFFFFFFF) {
1890 if (i & _S_IWRITE)
1891 attr &= ~FILE_ATTRIBUTE_READONLY;
1892 else
1893 attr |= FILE_ATTRIBUTE_READONLY;
1894 res = SetFileAttributesA(path, attr);
1895 }
1896 else
1897 res = 0;
1898 Py_END_ALLOW_THREADS
1899 if (!res) {
1900 win32_error("chmod", path);
1901 PyMem_Free(path);
1902 return NULL;
1903 }
1904 PyMem_Free(path);
1905 Py_INCREF(Py_None);
1906 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001907#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001908 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1909 &path, &i))
1910 return NULL;
1911 Py_BEGIN_ALLOW_THREADS
1912 res = chmod(path, i);
1913 Py_END_ALLOW_THREADS
1914 if (res < 0)
1915 return posix_error_with_allocated_filename(path);
1916 PyMem_Free(path);
1917 Py_INCREF(Py_None);
1918 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001919#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001920}
1921
Christian Heimes36281872007-11-30 21:11:28 +00001922#ifdef HAVE_FCHMOD
1923PyDoc_STRVAR(posix_fchmod__doc__,
1924"fchmod(fd, mode)\n\n\
1925Change the access permissions of the file given by file\n\
1926descriptor fd.");
1927
1928static PyObject *
1929posix_fchmod(PyObject *self, PyObject *args)
1930{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001931 int fd, mode, res;
1932 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1933 return NULL;
1934 Py_BEGIN_ALLOW_THREADS
1935 res = fchmod(fd, mode);
1936 Py_END_ALLOW_THREADS
1937 if (res < 0)
1938 return posix_error();
1939 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001940}
1941#endif /* HAVE_FCHMOD */
1942
1943#ifdef HAVE_LCHMOD
1944PyDoc_STRVAR(posix_lchmod__doc__,
1945"lchmod(path, mode)\n\n\
1946Change the access permissions of a file. If path is a symlink, this\n\
1947affects the link itself rather than the target.");
1948
1949static PyObject *
1950posix_lchmod(PyObject *self, PyObject *args)
1951{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001952 char *path = NULL;
1953 int i;
1954 int res;
1955 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1956 &path, &i))
1957 return NULL;
1958 Py_BEGIN_ALLOW_THREADS
1959 res = lchmod(path, i);
1960 Py_END_ALLOW_THREADS
1961 if (res < 0)
1962 return posix_error_with_allocated_filename(path);
1963 PyMem_Free(path);
1964 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001965}
1966#endif /* HAVE_LCHMOD */
1967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001968
Martin v. Löwis382abef2007-02-19 10:55:19 +00001969#ifdef HAVE_CHFLAGS
1970PyDoc_STRVAR(posix_chflags__doc__,
1971"chflags(path, flags)\n\n\
1972Set file flags.");
1973
1974static PyObject *
1975posix_chflags(PyObject *self, PyObject *args)
1976{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001977 char *path;
1978 unsigned long flags;
1979 int res;
1980 if (!PyArg_ParseTuple(args, "etk:chflags",
1981 Py_FileSystemDefaultEncoding, &path, &flags))
1982 return NULL;
1983 Py_BEGIN_ALLOW_THREADS
1984 res = chflags(path, flags);
1985 Py_END_ALLOW_THREADS
1986 if (res < 0)
1987 return posix_error_with_allocated_filename(path);
1988 PyMem_Free(path);
1989 Py_INCREF(Py_None);
1990 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001991}
1992#endif /* HAVE_CHFLAGS */
1993
1994#ifdef HAVE_LCHFLAGS
1995PyDoc_STRVAR(posix_lchflags__doc__,
1996"lchflags(path, flags)\n\n\
1997Set file flags.\n\
1998This function will not follow symbolic links.");
1999
2000static PyObject *
2001posix_lchflags(PyObject *self, PyObject *args)
2002{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002003 char *path;
2004 unsigned long flags;
2005 int res;
2006 if (!PyArg_ParseTuple(args, "etk:lchflags",
2007 Py_FileSystemDefaultEncoding, &path, &flags))
2008 return NULL;
2009 Py_BEGIN_ALLOW_THREADS
2010 res = lchflags(path, flags);
2011 Py_END_ALLOW_THREADS
2012 if (res < 0)
2013 return posix_error_with_allocated_filename(path);
2014 PyMem_Free(path);
2015 Py_INCREF(Py_None);
2016 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00002017}
2018#endif /* HAVE_LCHFLAGS */
2019
Martin v. Löwis244edc82001-10-04 22:44:26 +00002020#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002022"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002023Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00002024
2025static PyObject *
2026posix_chroot(PyObject *self, PyObject *args)
2027{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002028 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00002029}
2030#endif
2031
Guido van Rossum21142a01999-01-08 21:05:37 +00002032#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002034"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002035force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002036
2037static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002038posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002039{
Stefan Krah93f7a322010-11-26 17:35:50 +00002040 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002041}
2042#endif /* HAVE_FSYNC */
2043
2044#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00002045
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002046#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002047extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2048#endif
2049
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002050PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002051"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00002052force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00002054
2055static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00002056posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00002057{
Stefan Krah93f7a322010-11-26 17:35:50 +00002058 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002059}
2060#endif /* HAVE_FDATASYNC */
2061
2062
Fredrik Lundh10723342000-07-10 16:38:09 +00002063#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002065"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002067
Barry Warsaw53699e91996-12-10 23:23:01 +00002068static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002069posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002070{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002071 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002072 uid_t uid;
2073 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002074 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002075 if (!PyArg_ParseTuple(args, "etO&O&:chown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002076 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002077 _Py_Uid_Converter, &uid,
2078 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002079 return NULL;
2080 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002081 res = chown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002082 Py_END_ALLOW_THREADS
2083 if (res < 0)
2084 return posix_error_with_allocated_filename(path);
2085 PyMem_Free(path);
2086 Py_INCREF(Py_None);
2087 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002088}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002089#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002090
Christian Heimes36281872007-11-30 21:11:28 +00002091#ifdef HAVE_FCHOWN
2092PyDoc_STRVAR(posix_fchown__doc__,
2093"fchown(fd, uid, gid)\n\n\
2094Change the owner and group id of the file given by file descriptor\n\
2095fd to the numeric uid and gid.");
2096
2097static PyObject *
2098posix_fchown(PyObject *self, PyObject *args)
2099{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002100 int fd;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002101 uid_t uid;
2102 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002103 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002104 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd,
2105 _Py_Uid_Converter, &uid,
2106 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002107 return NULL;
2108 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002109 res = fchown(fd, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002110 Py_END_ALLOW_THREADS
2111 if (res < 0)
2112 return posix_error();
2113 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00002114}
2115#endif /* HAVE_FCHOWN */
2116
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002117#ifdef HAVE_LCHOWN
2118PyDoc_STRVAR(posix_lchown__doc__,
2119"lchown(path, uid, gid)\n\n\
2120Change the owner and group id of path to the numeric uid and gid.\n\
2121This function will not follow symbolic links.");
2122
2123static PyObject *
2124posix_lchown(PyObject *self, PyObject *args)
2125{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002126 char *path = NULL;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002127 uid_t uid;
2128 gid_t gid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002129 int res;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002130 if (!PyArg_ParseTuple(args, "etO&O&:lchown",
Victor Stinnerd6f85422010-05-05 23:33:33 +00002131 Py_FileSystemDefaultEncoding, &path,
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002132 _Py_Uid_Converter, &uid,
2133 _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00002134 return NULL;
2135 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02002136 res = lchown(path, uid, gid);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002137 Py_END_ALLOW_THREADS
2138 if (res < 0)
2139 return posix_error_with_allocated_filename(path);
2140 PyMem_Free(path);
2141 Py_INCREF(Py_None);
2142 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00002143}
2144#endif /* HAVE_LCHOWN */
2145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002146
Guido van Rossum36bc6801995-06-14 22:54:23 +00002147#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002148PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002149"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002150Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002151
Trent Nelsonda4277a2012-08-29 09:20:41 -04002152#if (defined(__sun) && defined(__SVR4)) || \
2153 defined(__OpenBSD__) || \
2154 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00002155/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
2156static PyObject *
2157posix_getcwd(PyObject *self, PyObject *noargs)
2158{
2159 char buf[PATH_MAX+2];
2160 char *res;
2161
2162 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00002163 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00002164 Py_END_ALLOW_THREADS
2165
2166 if (res == NULL)
2167 return posix_error();
2168
2169 return PyString_FromString(buf);
2170}
2171#else
Barry Warsaw53699e91996-12-10 23:23:01 +00002172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002173posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002174{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002175 int bufsize_incr = 1024;
2176 int bufsize = 0;
2177 char *tmpbuf = NULL;
2178 char *res = NULL;
2179 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00002180
Victor Stinnerd6f85422010-05-05 23:33:33 +00002181 Py_BEGIN_ALLOW_THREADS
2182 do {
2183 bufsize = bufsize + bufsize_incr;
2184 tmpbuf = malloc(bufsize);
2185 if (tmpbuf == NULL) {
2186 break;
2187 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002188#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002189 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002190#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002191 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002192#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002193
Victor Stinnerd6f85422010-05-05 23:33:33 +00002194 if (res == NULL) {
2195 free(tmpbuf);
2196 }
2197 } while ((res == NULL) && (errno == ERANGE));
2198 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002199
Victor Stinnerd6f85422010-05-05 23:33:33 +00002200 if (res == NULL)
2201 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002202
Victor Stinnerd6f85422010-05-05 23:33:33 +00002203 dynamic_return = PyString_FromString(tmpbuf);
2204 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002205
Victor Stinnerd6f85422010-05-05 23:33:33 +00002206 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002207}
Stefan Krah182ae642010-07-13 19:17:08 +00002208#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002209
Walter Dörwald3b918c32002-11-21 20:18:46 +00002210#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002211PyDoc_STRVAR(posix_getcwdu__doc__,
2212"getcwdu() -> path\n\n\
2213Return a unicode string representing the current working directory.");
2214
2215static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002216posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002217{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002218 char buf[1026];
2219 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002220
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002221#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002222 DWORD len;
2223 wchar_t wbuf[1026];
2224 wchar_t *wbuf2 = wbuf;
2225 PyObject *resobj;
2226 Py_BEGIN_ALLOW_THREADS
2227 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2228 /* If the buffer is large enough, len does not include the
2229 terminating \0. If the buffer is too small, len includes
2230 the space needed for the terminator. */
2231 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2232 wbuf2 = malloc(len * sizeof(wchar_t));
2233 if (wbuf2)
2234 len = GetCurrentDirectoryW(len, wbuf2);
2235 }
2236 Py_END_ALLOW_THREADS
2237 if (!wbuf2) {
2238 PyErr_NoMemory();
2239 return NULL;
2240 }
2241 if (!len) {
2242 if (wbuf2 != wbuf) free(wbuf2);
2243 return win32_error("getcwdu", NULL);
2244 }
2245 resobj = PyUnicode_FromWideChar(wbuf2, len);
2246 if (wbuf2 != wbuf) free(wbuf2);
2247 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002248#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002249
Victor Stinnerd6f85422010-05-05 23:33:33 +00002250 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002251#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002252 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002253#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002254 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002255#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002256 Py_END_ALLOW_THREADS
2257 if (res == NULL)
2258 return posix_error();
2259 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002260}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002261#endif /* Py_USING_UNICODE */
2262#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002263
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002264
Guido van Rossumb6775db1994-08-01 11:34:53 +00002265#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002266PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002267"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002268Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002269
Barry Warsaw53699e91996-12-10 23:23:01 +00002270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002271posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002272{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002273 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002274}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002275#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002276
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002277
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002278PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002279"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002280Return a list containing the names of the entries in the directory.\n\
2281\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002282 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002283\n\
2284The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002285entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002286
Barry Warsaw53699e91996-12-10 23:23:01 +00002287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002288posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002289{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002290 /* XXX Should redo this putting the (now four) versions of opendir
2291 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002292#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002293
Victor Stinnerd6f85422010-05-05 23:33:33 +00002294 PyObject *d, *v;
2295 HANDLE hFindFile;
2296 BOOL result;
2297 WIN32_FIND_DATA FileData;
2298 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2299 char *bufptr = namebuf;
2300 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002301
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002302 Py_UNICODE *wpath;
2303 if (PyArg_ParseTuple(args, "u:listdir", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002304 WIN32_FIND_DATAW wFileData;
2305 Py_UNICODE *wnamebuf;
2306 /* Overallocate for \\*.*\0 */
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002307 len = wcslen(wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002308 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2309 if (!wnamebuf) {
2310 PyErr_NoMemory();
2311 return NULL;
2312 }
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002313 wcscpy(wnamebuf, wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002314 if (len > 0) {
2315 Py_UNICODE wch = wnamebuf[len-1];
2316 if (wch != L'/' && wch != L'\\' && wch != L':')
2317 wnamebuf[len++] = L'\\';
2318 wcscpy(wnamebuf + len, L"*.*");
2319 }
2320 if ((d = PyList_New(0)) == NULL) {
2321 free(wnamebuf);
2322 return NULL;
2323 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002324 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002325 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002326 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002327 if (hFindFile == INVALID_HANDLE_VALUE) {
2328 int error = GetLastError();
2329 if (error == ERROR_FILE_NOT_FOUND) {
2330 free(wnamebuf);
2331 return d;
2332 }
2333 Py_DECREF(d);
2334 win32_error_unicode("FindFirstFileW", wnamebuf);
2335 free(wnamebuf);
2336 return NULL;
2337 }
2338 do {
2339 /* Skip over . and .. */
2340 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2341 wcscmp(wFileData.cFileName, L"..") != 0) {
2342 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2343 if (v == NULL) {
2344 Py_DECREF(d);
2345 d = NULL;
2346 break;
2347 }
2348 if (PyList_Append(d, v) != 0) {
2349 Py_DECREF(v);
2350 Py_DECREF(d);
2351 d = NULL;
2352 break;
2353 }
2354 Py_DECREF(v);
2355 }
2356 Py_BEGIN_ALLOW_THREADS
2357 result = FindNextFileW(hFindFile, &wFileData);
2358 Py_END_ALLOW_THREADS
2359 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2360 it got to the end of the directory. */
2361 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2362 Py_DECREF(d);
2363 win32_error_unicode("FindNextFileW", wnamebuf);
2364 FindClose(hFindFile);
2365 free(wnamebuf);
2366 return NULL;
2367 }
2368 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002369
Victor Stinnerd6f85422010-05-05 23:33:33 +00002370 if (FindClose(hFindFile) == FALSE) {
2371 Py_DECREF(d);
2372 win32_error_unicode("FindClose", wnamebuf);
2373 free(wnamebuf);
2374 return NULL;
2375 }
2376 free(wnamebuf);
2377 return d;
2378 }
2379 /* Drop the argument parsing error as narrow strings
2380 are also valid. */
2381 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002382
Victor Stinnerd6f85422010-05-05 23:33:33 +00002383 if (!PyArg_ParseTuple(args, "et#:listdir",
2384 Py_FileSystemDefaultEncoding, &bufptr, &len))
2385 return NULL;
2386 if (len > 0) {
2387 char ch = namebuf[len-1];
2388 if (ch != SEP && ch != ALTSEP && ch != ':')
Anthony Sottile27f32e92018-01-15 13:39:04 -08002389 namebuf[len++] = SEP;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002390 strcpy(namebuf + len, "*.*");
2391 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002392
Victor Stinnerd6f85422010-05-05 23:33:33 +00002393 if ((d = PyList_New(0)) == NULL)
2394 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002395
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002396 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002397 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002398 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002399 if (hFindFile == INVALID_HANDLE_VALUE) {
2400 int error = GetLastError();
2401 if (error == ERROR_FILE_NOT_FOUND)
2402 return d;
2403 Py_DECREF(d);
2404 return win32_error("FindFirstFile", namebuf);
2405 }
2406 do {
2407 /* Skip over . and .. */
2408 if (strcmp(FileData.cFileName, ".") != 0 &&
2409 strcmp(FileData.cFileName, "..") != 0) {
2410 v = PyString_FromString(FileData.cFileName);
2411 if (v == NULL) {
2412 Py_DECREF(d);
2413 d = NULL;
2414 break;
2415 }
2416 if (PyList_Append(d, v) != 0) {
2417 Py_DECREF(v);
2418 Py_DECREF(d);
2419 d = NULL;
2420 break;
2421 }
2422 Py_DECREF(v);
2423 }
2424 Py_BEGIN_ALLOW_THREADS
2425 result = FindNextFile(hFindFile, &FileData);
2426 Py_END_ALLOW_THREADS
2427 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2428 it got to the end of the directory. */
2429 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2430 Py_DECREF(d);
2431 win32_error("FindNextFile", namebuf);
2432 FindClose(hFindFile);
2433 return NULL;
2434 }
2435 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002436
Victor Stinnerd6f85422010-05-05 23:33:33 +00002437 if (FindClose(hFindFile) == FALSE) {
2438 Py_DECREF(d);
2439 return win32_error("FindClose", namebuf);
2440 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002441
Victor Stinnerd6f85422010-05-05 23:33:33 +00002442 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002443
Tim Peters0bb44a42000-09-15 07:44:49 +00002444#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002445
2446#ifndef MAX_PATH
2447#define MAX_PATH CCHMAXPATH
2448#endif
2449 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002450 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002451 PyObject *d, *v;
2452 char namebuf[MAX_PATH+5];
2453 HDIR hdir = 1;
2454 ULONG srchcnt = 1;
2455 FILEFINDBUF3 ep;
2456 APIRET rc;
2457
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002458 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002459 return NULL;
2460 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002461 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002462 return NULL;
2463 }
2464 strcpy(namebuf, name);
2465 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002466 if (*pt == ALTSEP)
2467 *pt = SEP;
2468 if (namebuf[len-1] != SEP)
2469 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002470 strcpy(namebuf + len, "*.*");
2471
Victor Stinnerd6f85422010-05-05 23:33:33 +00002472 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002473 return NULL;
2474
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002475 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2476 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002477 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002478 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2479 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2480 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002481
2482 if (rc != NO_ERROR) {
2483 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002484 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002485 }
2486
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002487 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002488 do {
2489 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002490 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002491 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002492
2493 strcpy(namebuf, ep.achName);
2494
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002495 /* Leave Case of Name Alone -- In Native Form */
2496 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002497
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002498 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002499 if (v == NULL) {
2500 Py_DECREF(d);
2501 d = NULL;
2502 break;
2503 }
2504 if (PyList_Append(d, v) != 0) {
2505 Py_DECREF(v);
2506 Py_DECREF(d);
2507 d = NULL;
2508 break;
2509 }
2510 Py_DECREF(v);
2511 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2512 }
2513
2514 return d;
2515#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002516
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 char *name = NULL;
2518 PyObject *d, *v;
2519 DIR *dirp;
2520 struct dirent *ep;
2521 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002522
Victor Stinnerd6f85422010-05-05 23:33:33 +00002523 errno = 0;
2524 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2525 arg_is_unicode = 0;
2526 PyErr_Clear();
2527 }
2528 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2529 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002530 Py_BEGIN_ALLOW_THREADS
2531 dirp = opendir(name);
2532 Py_END_ALLOW_THREADS
2533 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002534 return posix_error_with_allocated_filename(name);
2535 }
2536 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002537 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002538 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002539 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002540 PyMem_Free(name);
2541 return NULL;
2542 }
2543 for (;;) {
2544 errno = 0;
2545 Py_BEGIN_ALLOW_THREADS
2546 ep = readdir(dirp);
2547 Py_END_ALLOW_THREADS
2548 if (ep == NULL) {
2549 if (errno == 0) {
2550 break;
2551 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002552 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002553 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002554 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002555 Py_DECREF(d);
2556 return posix_error_with_allocated_filename(name);
2557 }
2558 }
2559 if (ep->d_name[0] == '.' &&
2560 (NAMLEN(ep) == 1 ||
2561 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2562 continue;
2563 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2564 if (v == NULL) {
2565 Py_DECREF(d);
2566 d = NULL;
2567 break;
2568 }
Just van Rossum46c97842003-02-25 21:42:15 +00002569#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002570 if (arg_is_unicode) {
2571 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002572
Victor Stinnerd6f85422010-05-05 23:33:33 +00002573 w = PyUnicode_FromEncodedObject(v,
2574 Py_FileSystemDefaultEncoding,
2575 "strict");
2576 if (w != NULL) {
2577 Py_DECREF(v);
2578 v = w;
2579 }
2580 else {
2581 /* fall back to the original byte string, as
2582 discussed in patch #683592 */
2583 PyErr_Clear();
2584 }
2585 }
Just van Rossum46c97842003-02-25 21:42:15 +00002586#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002587 if (PyList_Append(d, v) != 0) {
2588 Py_DECREF(v);
2589 Py_DECREF(d);
2590 d = NULL;
2591 break;
2592 }
2593 Py_DECREF(v);
2594 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002595 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002596 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002597 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002598 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002599
Victor Stinnerd6f85422010-05-05 23:33:33 +00002600 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002601
Tim Peters0bb44a42000-09-15 07:44:49 +00002602#endif /* which OS */
2603} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002604
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002605#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002606/* A helper function for abspath on win32 */
2607static PyObject *
2608posix__getfullpathname(PyObject *self, PyObject *args)
2609{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002610 /* assume encoded strings won't more than double no of chars */
2611 char inbuf[MAX_PATH*2];
2612 char *inbufp = inbuf;
2613 Py_ssize_t insize = sizeof(inbuf);
2614 char outbuf[MAX_PATH*2];
2615 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002616
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002617 Py_UNICODE *wpath;
2618 if (PyArg_ParseTuple(args, "u|:_getfullpathname", &wpath)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002619 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2620 Py_UNICODE *wtemp;
2621 DWORD result;
2622 PyObject *v;
2623 result = GetFullPathNameW(wpath,
2624 sizeof(woutbuf)/sizeof(woutbuf[0]),
2625 woutbuf, &wtemp);
2626 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2627 woutbufp = malloc(result * sizeof(Py_UNICODE));
2628 if (!woutbufp)
2629 return PyErr_NoMemory();
2630 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2631 }
2632 if (result)
2633 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2634 else
2635 v = win32_error_unicode("GetFullPathNameW", wpath);
2636 if (woutbufp != woutbuf)
2637 free(woutbufp);
2638 return v;
2639 }
2640 /* Drop the argument parsing error as narrow strings
2641 are also valid. */
2642 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002643
Victor Stinnerd6f85422010-05-05 23:33:33 +00002644 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2645 Py_FileSystemDefaultEncoding, &inbufp,
2646 &insize))
2647 return NULL;
2648 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2649 outbuf, &temp))
2650 return win32_error("GetFullPathName", inbuf);
2651 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2652 return PyUnicode_Decode(outbuf, strlen(outbuf),
2653 Py_FileSystemDefaultEncoding, NULL);
2654 }
2655 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002656} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002657#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002660"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Barry Warsaw53699e91996-12-10 23:23:01 +00002663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002664posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002666 int res;
2667 char *path = NULL;
2668 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002669
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002670#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002671 Py_UNICODE *wpath;
2672 if (PyArg_ParseTuple(args, "u|i:mkdir", &wpath, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002673 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002674 res = CreateDirectoryW(wpath, NULL);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002675 Py_END_ALLOW_THREADS
2676 if (!res)
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002677 return win32_error_unicode("mkdir", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002678 Py_INCREF(Py_None);
2679 return Py_None;
2680 }
2681 /* Drop the argument parsing error as narrow strings
2682 are also valid. */
2683 PyErr_Clear();
2684 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2685 Py_FileSystemDefaultEncoding, &path, &mode))
2686 return NULL;
2687 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002688 res = CreateDirectoryA(path, NULL);
2689 Py_END_ALLOW_THREADS
2690 if (!res) {
2691 win32_error("mkdir", path);
2692 PyMem_Free(path);
2693 return NULL;
2694 }
2695 PyMem_Free(path);
2696 Py_INCREF(Py_None);
2697 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002698#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002699
Victor Stinnerd6f85422010-05-05 23:33:33 +00002700 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2701 Py_FileSystemDefaultEncoding, &path, &mode))
2702 return NULL;
2703 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002704#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002705 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002706#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002707 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002708#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002709 Py_END_ALLOW_THREADS
2710 if (res < 0)
2711 return posix_error_with_allocated_filename(path);
2712 PyMem_Free(path);
2713 Py_INCREF(Py_None);
2714 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002715#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002716}
2717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002718
Neal Norwitz1818ed72006-03-26 00:29:48 +00002719/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2720#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002721#include <sys/resource.h>
2722#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002723
Neal Norwitz1818ed72006-03-26 00:29:48 +00002724
2725#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002727"nice(inc) -> new_priority\n\n\
2728Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002729
Barry Warsaw53699e91996-12-10 23:23:01 +00002730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002731posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002732{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002733 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002734
Victor Stinnerd6f85422010-05-05 23:33:33 +00002735 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2736 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002737
Victor Stinnerd6f85422010-05-05 23:33:33 +00002738 /* There are two flavours of 'nice': one that returns the new
2739 priority (as required by almost all standards out there) and the
2740 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2741 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002742
Victor Stinnerd6f85422010-05-05 23:33:33 +00002743 If we are of the nice family that returns the new priority, we
2744 need to clear errno before the call, and check if errno is filled
2745 before calling posix_error() on a returnvalue of -1, because the
2746 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002747
Victor Stinnerd6f85422010-05-05 23:33:33 +00002748 errno = 0;
2749 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002750#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002751 if (value == 0)
2752 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002753#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002754 if (value == -1 && errno != 0)
2755 /* either nice() or getpriority() returned an error */
2756 return posix_error();
2757 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002758}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002759#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002761PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002762"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002763Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Barry Warsaw53699e91996-12-10 23:23:01 +00002765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002766posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002767{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002768#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002769 PyObject *o1, *o2;
2770 char *p1, *p2;
2771 BOOL result;
2772 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2773 goto error;
2774 if (!convert_to_unicode(&o1))
2775 goto error;
2776 if (!convert_to_unicode(&o2)) {
2777 Py_DECREF(o1);
2778 goto error;
2779 }
2780 Py_BEGIN_ALLOW_THREADS
2781 result = MoveFileW(PyUnicode_AsUnicode(o1),
2782 PyUnicode_AsUnicode(o2));
2783 Py_END_ALLOW_THREADS
2784 Py_DECREF(o1);
2785 Py_DECREF(o2);
2786 if (!result)
2787 return win32_error("rename", NULL);
2788 Py_INCREF(Py_None);
2789 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002790error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002791 PyErr_Clear();
2792 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2793 return NULL;
2794 Py_BEGIN_ALLOW_THREADS
2795 result = MoveFileA(p1, p2);
2796 Py_END_ALLOW_THREADS
2797 if (!result)
2798 return win32_error("rename", NULL);
2799 Py_INCREF(Py_None);
2800 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002801#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002802 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002803#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002804}
2805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002806
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002807PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002808"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002809Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002810
Barry Warsaw53699e91996-12-10 23:23:01 +00002811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002812posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002813{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002814#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002815 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002816#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002817 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002818#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002819}
2820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002822PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002823"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002825
Barry Warsaw53699e91996-12-10 23:23:01 +00002826static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002827posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002828{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002829#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002830 return posix_do_stat(self, args, "et:stat", STAT, "u:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002831#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002832 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002833#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002834}
2835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002837#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002838PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002839"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002840Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002841
Barry Warsaw53699e91996-12-10 23:23:01 +00002842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002843posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002844{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002845 char *command;
2846 long sts;
2847 if (!PyArg_ParseTuple(args, "s:system", &command))
2848 return NULL;
2849 Py_BEGIN_ALLOW_THREADS
2850 sts = system(command);
2851 Py_END_ALLOW_THREADS
2852 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002853}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002854#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002857PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002858"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002859Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002860
Barry Warsaw53699e91996-12-10 23:23:01 +00002861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002862posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002863{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002864 int i;
2865 if (!PyArg_ParseTuple(args, "i:umask", &i))
2866 return NULL;
2867 i = (int)umask(i);
2868 if (i < 0)
2869 return posix_error();
2870 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002871}
2872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002874PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002875"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002876Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002878PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002879"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002880Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002881
Barry Warsaw53699e91996-12-10 23:23:01 +00002882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002883posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002884{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002885#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002886 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002887#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002888 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002889#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890}
2891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002892
Guido van Rossumb6775db1994-08-01 11:34:53 +00002893#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002894PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002895"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002896Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002897
Barry Warsaw53699e91996-12-10 23:23:01 +00002898static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002899posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002900{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002901 struct utsname u;
2902 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002903
Victor Stinnerd6f85422010-05-05 23:33:33 +00002904 Py_BEGIN_ALLOW_THREADS
2905 res = uname(&u);
2906 Py_END_ALLOW_THREADS
2907 if (res < 0)
2908 return posix_error();
2909 return Py_BuildValue("(sssss)",
2910 u.sysname,
2911 u.nodename,
2912 u.release,
2913 u.version,
2914 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002915}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002916#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002917
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002918static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002919extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002920{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002921 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002922 if (PyFloat_Check(t)) {
2923 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002924 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002925 if (!intobj)
2926 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002927#if SIZEOF_TIME_T > SIZEOF_LONG
2928 intval = PyInt_AsUnsignedLongLongMask(intobj);
2929#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002930 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002931#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002932 Py_DECREF(intobj);
2933 if (intval == -1 && PyErr_Occurred())
2934 return -1;
2935 *sec = intval;
2936 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2937 if (*usec < 0)
2938 /* If rounding gave us a negative number,
2939 truncate. */
2940 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002941 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002942 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002943#if SIZEOF_TIME_T > SIZEOF_LONG
2944 intval = PyInt_AsUnsignedLongLongMask(t);
2945#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002946 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002947#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002948 if (intval == -1 && PyErr_Occurred())
2949 return -1;
2950 *sec = intval;
2951 *usec = 0;
2952 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002953}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002955PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002956"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002957utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002958Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002960
Barry Warsaw53699e91996-12-10 23:23:01 +00002961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002962posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002963{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002964#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002965 PyObject *arg;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002966 wchar_t *wpath = NULL;
2967 char *apath = NULL;
2968 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002969 time_t atimesec, mtimesec;
2970 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002971 FILETIME atime, mtime;
2972 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002973
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03002974 if (PyArg_ParseTuple(args, "uO|:utime", &wpath, &arg)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002975 Py_BEGIN_ALLOW_THREADS
2976 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2977 NULL, OPEN_EXISTING,
2978 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2979 Py_END_ALLOW_THREADS
2980 if (hFile == INVALID_HANDLE_VALUE)
2981 return win32_error_unicode("utime", wpath);
2982 } else
2983 /* Drop the argument parsing error as narrow strings
2984 are also valid. */
2985 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002986
Victor Stinnerd6f85422010-05-05 23:33:33 +00002987 if (!wpath) {
2988 if (!PyArg_ParseTuple(args, "etO:utime",
2989 Py_FileSystemDefaultEncoding, &apath, &arg))
2990 return NULL;
2991 Py_BEGIN_ALLOW_THREADS
2992 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2993 NULL, OPEN_EXISTING,
2994 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2995 Py_END_ALLOW_THREADS
2996 if (hFile == INVALID_HANDLE_VALUE) {
2997 win32_error("utime", apath);
2998 PyMem_Free(apath);
2999 return NULL;
3000 }
3001 PyMem_Free(apath);
3002 }
3003
3004 if (arg == Py_None) {
3005 SYSTEMTIME now;
3006 GetSystemTime(&now);
3007 if (!SystemTimeToFileTime(&now, &mtime) ||
3008 !SystemTimeToFileTime(&now, &atime)) {
3009 win32_error("utime", NULL);
3010 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00003011 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003012 }
3013 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3014 PyErr_SetString(PyExc_TypeError,
3015 "utime() arg 2 must be a tuple (atime, mtime)");
3016 goto done;
3017 }
3018 else {
3019 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3020 &atimesec, &ausec) == -1)
3021 goto done;
3022 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
3023 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3024 &mtimesec, &musec) == -1)
3025 goto done;
3026 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
3027 }
3028 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
3029 /* Avoid putting the file name into the error here,
3030 as that may confuse the user into believing that
3031 something is wrong with the file, when it also
3032 could be the time stamp that gives a problem. */
3033 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00003034 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003035 }
3036 Py_INCREF(Py_None);
3037 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003038done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003039 CloseHandle(hFile);
3040 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003041#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00003042
Victor Stinnerd6f85422010-05-05 23:33:33 +00003043 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00003044 time_t atime, mtime;
3045 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003046 int res;
3047 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003048
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003049#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003050 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003051#define ATIME buf[0].tv_sec
3052#define MTIME buf[1].tv_sec
3053#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00003054/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003055 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003056#define ATIME buf.actime
3057#define MTIME buf.modtime
3058#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003059#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003060 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003061#define ATIME buf[0]
3062#define MTIME buf[1]
3063#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003064#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003065
Mark Hammond817c9292003-12-03 01:22:38 +00003066
Victor Stinnerd6f85422010-05-05 23:33:33 +00003067 if (!PyArg_ParseTuple(args, "etO:utime",
3068 Py_FileSystemDefaultEncoding, &path, &arg))
3069 return NULL;
3070 if (arg == Py_None) {
3071 /* optional time values not given */
3072 Py_BEGIN_ALLOW_THREADS
3073 res = utime(path, NULL);
3074 Py_END_ALLOW_THREADS
3075 }
3076 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
3077 PyErr_SetString(PyExc_TypeError,
3078 "utime() arg 2 must be a tuple (atime, mtime)");
3079 PyMem_Free(path);
3080 return NULL;
3081 }
3082 else {
3083 if (extract_time(PyTuple_GET_ITEM(arg, 0),
3084 &atime, &ausec) == -1) {
3085 PyMem_Free(path);
3086 return NULL;
3087 }
3088 if (extract_time(PyTuple_GET_ITEM(arg, 1),
3089 &mtime, &musec) == -1) {
3090 PyMem_Free(path);
3091 return NULL;
3092 }
3093 ATIME = atime;
3094 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003095#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00003096 buf[0].tv_usec = ausec;
3097 buf[1].tv_usec = musec;
3098 Py_BEGIN_ALLOW_THREADS
3099 res = utimes(path, buf);
3100 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00003101#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003102 Py_BEGIN_ALLOW_THREADS
3103 res = utime(path, UTIME_ARG);
3104 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00003105#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003106 }
3107 if (res < 0) {
3108 return posix_error_with_allocated_filename(path);
3109 }
3110 PyMem_Free(path);
3111 Py_INCREF(Py_None);
3112 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003113#undef UTIME_ARG
3114#undef ATIME
3115#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00003116#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003117}
3118
Guido van Rossum85e3b011991-06-03 12:42:10 +00003119
Guido van Rossum3b066191991-06-04 19:40:25 +00003120/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003121
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003122PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003123"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003124Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003125
Barry Warsaw53699e91996-12-10 23:23:01 +00003126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003127posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003128{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003129 int sts;
3130 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
3131 return NULL;
3132 _exit(sts);
3133 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003134}
3135
Martin v. Löwis114619e2002-10-07 06:44:21 +00003136#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
3137static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00003138free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00003139{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003140 Py_ssize_t i;
3141 for (i = 0; i < count; i++)
3142 PyMem_Free(array[i]);
3143 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003144}
3145#endif
3146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003147
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003148#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003149PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003150"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003151Execute an executable path with arguments, replacing current process.\n\
3152\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003153 path: path of executable file\n\
3154 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Barry Warsaw53699e91996-12-10 23:23:01 +00003156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003157posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003158{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 char *path;
3160 PyObject *argv;
3161 char **argvlist;
3162 Py_ssize_t i, argc;
3163 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003164
Victor Stinnerd6f85422010-05-05 23:33:33 +00003165 /* execv has two arguments: (path, argv), where
3166 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003167
Victor Stinnerd6f85422010-05-05 23:33:33 +00003168 if (!PyArg_ParseTuple(args, "etO:execv",
3169 Py_FileSystemDefaultEncoding,
3170 &path, &argv))
3171 return NULL;
3172 if (PyList_Check(argv)) {
3173 argc = PyList_Size(argv);
3174 getitem = PyList_GetItem;
3175 }
3176 else if (PyTuple_Check(argv)) {
3177 argc = PyTuple_Size(argv);
3178 getitem = PyTuple_GetItem;
3179 }
3180 else {
3181 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
3182 PyMem_Free(path);
3183 return NULL;
3184 }
3185 if (argc < 1) {
3186 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3187 PyMem_Free(path);
3188 return NULL;
3189 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003190
Victor Stinnerd6f85422010-05-05 23:33:33 +00003191 argvlist = PyMem_NEW(char *, argc+1);
3192 if (argvlist == NULL) {
3193 PyMem_Free(path);
3194 return PyErr_NoMemory();
3195 }
3196 for (i = 0; i < argc; i++) {
3197 if (!PyArg_Parse((*getitem)(argv, i), "et",
3198 Py_FileSystemDefaultEncoding,
3199 &argvlist[i])) {
3200 free_string_array(argvlist, i);
3201 PyErr_SetString(PyExc_TypeError,
3202 "execv() arg 2 must contain only strings");
3203 PyMem_Free(path);
3204 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003205
Victor Stinnerd6f85422010-05-05 23:33:33 +00003206 }
3207 }
3208 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003209
Victor Stinnerd6f85422010-05-05 23:33:33 +00003210 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003211
Victor Stinnerd6f85422010-05-05 23:33:33 +00003212 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003213
Victor Stinnerd6f85422010-05-05 23:33:33 +00003214 free_string_array(argvlist, argc);
3215 PyMem_Free(path);
3216 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003217}
3218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003220PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003221"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003222Execute a path with arguments and environment, replacing current process.\n\
3223\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003224 path: path of executable file\n\
3225 args: tuple or list of arguments\n\
3226 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003227
Barry Warsaw53699e91996-12-10 23:23:01 +00003228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003229posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003230{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003231 char *path;
3232 PyObject *argv, *env;
3233 char **argvlist;
3234 char **envlist;
3235 PyObject *key, *val, *keys=NULL, *vals=NULL;
3236 Py_ssize_t i, pos, argc, envc;
3237 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3238 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003239
Victor Stinnerd6f85422010-05-05 23:33:33 +00003240 /* execve has three arguments: (path, argv, env), where
3241 argv is a list or tuple of strings and env is a dictionary
3242 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003243
Victor Stinnerd6f85422010-05-05 23:33:33 +00003244 if (!PyArg_ParseTuple(args, "etOO:execve",
3245 Py_FileSystemDefaultEncoding,
3246 &path, &argv, &env))
3247 return NULL;
3248 if (PyList_Check(argv)) {
3249 argc = PyList_Size(argv);
3250 getitem = PyList_GetItem;
3251 }
3252 else if (PyTuple_Check(argv)) {
3253 argc = PyTuple_Size(argv);
3254 getitem = PyTuple_GetItem;
3255 }
3256 else {
3257 PyErr_SetString(PyExc_TypeError,
3258 "execve() arg 2 must be a tuple or list");
3259 goto fail_0;
3260 }
3261 if (!PyMapping_Check(env)) {
3262 PyErr_SetString(PyExc_TypeError,
3263 "execve() arg 3 must be a mapping object");
3264 goto fail_0;
3265 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003266
Victor Stinnerd6f85422010-05-05 23:33:33 +00003267 argvlist = PyMem_NEW(char *, argc+1);
3268 if (argvlist == NULL) {
3269 PyErr_NoMemory();
3270 goto fail_0;
3271 }
3272 for (i = 0; i < argc; i++) {
3273 if (!PyArg_Parse((*getitem)(argv, i),
3274 "et;execve() arg 2 must contain only strings",
3275 Py_FileSystemDefaultEncoding,
3276 &argvlist[i]))
3277 {
3278 lastarg = i;
3279 goto fail_1;
3280 }
3281 }
3282 lastarg = argc;
3283 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003284
Victor Stinnerd6f85422010-05-05 23:33:33 +00003285 i = PyMapping_Size(env);
3286 if (i < 0)
3287 goto fail_1;
3288 envlist = PyMem_NEW(char *, i + 1);
3289 if (envlist == NULL) {
3290 PyErr_NoMemory();
3291 goto fail_1;
3292 }
3293 envc = 0;
3294 keys = PyMapping_Keys(env);
3295 vals = PyMapping_Values(env);
3296 if (!keys || !vals)
3297 goto fail_2;
3298 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3299 PyErr_SetString(PyExc_TypeError,
3300 "execve(): env.keys() or env.values() is not a list");
3301 goto fail_2;
3302 }
Tim Peters5aa91602002-01-30 05:46:57 +00003303
Victor Stinnerd6f85422010-05-05 23:33:33 +00003304 for (pos = 0; pos < i; pos++) {
3305 char *p, *k, *v;
3306 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003307
Victor Stinnerd6f85422010-05-05 23:33:33 +00003308 key = PyList_GetItem(keys, pos);
3309 val = PyList_GetItem(vals, pos);
3310 if (!key || !val)
3311 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003312
Victor Stinnerd6f85422010-05-05 23:33:33 +00003313 if (!PyArg_Parse(
3314 key,
3315 "s;execve() arg 3 contains a non-string key",
3316 &k) ||
3317 !PyArg_Parse(
3318 val,
3319 "s;execve() arg 3 contains a non-string value",
3320 &v))
3321 {
3322 goto fail_2;
3323 }
Serhiy Storchaka9dda2ca2017-06-24 11:49:00 +03003324 /* Search from index 1 because on Windows starting '=' is allowed for
3325 defining hidden environment variables. */
3326 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3327 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3328 goto fail_2;
3329 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003330
3331#if defined(PYOS_OS2)
3332 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3333 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3334#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003335 len = PyString_Size(key) + PyString_Size(val) + 2;
3336 p = PyMem_NEW(char, len);
3337 if (p == NULL) {
3338 PyErr_NoMemory();
3339 goto fail_2;
3340 }
3341 PyOS_snprintf(p, len, "%s=%s", k, v);
3342 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003343#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003344 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003345#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003346 }
3347 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003348
Victor Stinnerd6f85422010-05-05 23:33:33 +00003349 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003350
Victor Stinnerd6f85422010-05-05 23:33:33 +00003351 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003352
Victor Stinnerd6f85422010-05-05 23:33:33 +00003353 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003354
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003355 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003356 while (--envc >= 0)
3357 PyMem_DEL(envlist[envc]);
3358 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003359 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003360 free_string_array(argvlist, lastarg);
3361 Py_XDECREF(vals);
3362 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003363 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003364 PyMem_Free(path);
3365 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003366}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003367#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003369
Guido van Rossuma1065681999-01-25 23:20:23 +00003370#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003371PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003372"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003373Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003374\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003375 mode: mode of process creation\n\
3376 path: path of executable file\n\
3377 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003378
3379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003380posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003381{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003382 char *path;
3383 PyObject *argv;
3384 char **argvlist;
3385 int mode, i;
3386 Py_ssize_t argc;
3387 Py_intptr_t spawnval;
3388 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003389
Victor Stinnerd6f85422010-05-05 23:33:33 +00003390 /* spawnv has three arguments: (mode, path, argv), where
3391 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003392
Victor Stinnerd6f85422010-05-05 23:33:33 +00003393 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3394 Py_FileSystemDefaultEncoding,
3395 &path, &argv))
3396 return NULL;
3397 if (PyList_Check(argv)) {
3398 argc = PyList_Size(argv);
3399 getitem = PyList_GetItem;
3400 }
3401 else if (PyTuple_Check(argv)) {
3402 argc = PyTuple_Size(argv);
3403 getitem = PyTuple_GetItem;
3404 }
3405 else {
3406 PyErr_SetString(PyExc_TypeError,
3407 "spawnv() arg 2 must be a tuple or list");
3408 PyMem_Free(path);
3409 return NULL;
3410 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003411
Victor Stinnerd6f85422010-05-05 23:33:33 +00003412 argvlist = PyMem_NEW(char *, argc+1);
3413 if (argvlist == NULL) {
3414 PyMem_Free(path);
3415 return PyErr_NoMemory();
3416 }
3417 for (i = 0; i < argc; i++) {
3418 if (!PyArg_Parse((*getitem)(argv, i), "et",
3419 Py_FileSystemDefaultEncoding,
3420 &argvlist[i])) {
3421 free_string_array(argvlist, i);
3422 PyErr_SetString(
3423 PyExc_TypeError,
3424 "spawnv() arg 2 must contain only strings");
3425 PyMem_Free(path);
3426 return NULL;
3427 }
3428 }
3429 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003430
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003431#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003432 Py_BEGIN_ALLOW_THREADS
3433 spawnval = spawnv(mode, path, argvlist);
3434 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003435#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003436 if (mode == _OLD_P_OVERLAY)
3437 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003438
Victor Stinnerd6f85422010-05-05 23:33:33 +00003439 Py_BEGIN_ALLOW_THREADS
3440 spawnval = _spawnv(mode, path, argvlist);
3441 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003442#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003443
Victor Stinnerd6f85422010-05-05 23:33:33 +00003444 free_string_array(argvlist, argc);
3445 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003446
Victor Stinnerd6f85422010-05-05 23:33:33 +00003447 if (spawnval == -1)
3448 return posix_error();
3449 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003450#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003451 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003452#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003453 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003454#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003455}
3456
3457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003458PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003459"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003460Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003461\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003462 mode: mode of process creation\n\
3463 path: path of executable file\n\
3464 args: tuple or list of arguments\n\
3465 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003466
3467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003468posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003469{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003470 char *path;
3471 PyObject *argv, *env;
3472 char **argvlist;
3473 char **envlist;
3474 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3475 int mode, pos, envc;
3476 Py_ssize_t argc, i;
3477 Py_intptr_t spawnval;
3478 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3479 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003480
Victor Stinnerd6f85422010-05-05 23:33:33 +00003481 /* spawnve has four arguments: (mode, path, argv, env), where
3482 argv is a list or tuple of strings and env is a dictionary
3483 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003484
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3486 Py_FileSystemDefaultEncoding,
3487 &path, &argv, &env))
3488 return NULL;
3489 if (PyList_Check(argv)) {
3490 argc = PyList_Size(argv);
3491 getitem = PyList_GetItem;
3492 }
3493 else if (PyTuple_Check(argv)) {
3494 argc = PyTuple_Size(argv);
3495 getitem = PyTuple_GetItem;
3496 }
3497 else {
3498 PyErr_SetString(PyExc_TypeError,
3499 "spawnve() arg 2 must be a tuple or list");
3500 goto fail_0;
3501 }
3502 if (!PyMapping_Check(env)) {
3503 PyErr_SetString(PyExc_TypeError,
3504 "spawnve() arg 3 must be a mapping object");
3505 goto fail_0;
3506 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003507
Victor Stinnerd6f85422010-05-05 23:33:33 +00003508 argvlist = PyMem_NEW(char *, argc+1);
3509 if (argvlist == NULL) {
3510 PyErr_NoMemory();
3511 goto fail_0;
3512 }
3513 for (i = 0; i < argc; i++) {
3514 if (!PyArg_Parse((*getitem)(argv, i),
3515 "et;spawnve() arg 2 must contain only strings",
3516 Py_FileSystemDefaultEncoding,
3517 &argvlist[i]))
3518 {
3519 lastarg = i;
3520 goto fail_1;
3521 }
3522 }
3523 lastarg = argc;
3524 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003525
Victor Stinnerd6f85422010-05-05 23:33:33 +00003526 i = PyMapping_Size(env);
3527 if (i < 0)
3528 goto fail_1;
3529 envlist = PyMem_NEW(char *, i + 1);
3530 if (envlist == NULL) {
3531 PyErr_NoMemory();
3532 goto fail_1;
3533 }
3534 envc = 0;
3535 keys = PyMapping_Keys(env);
3536 vals = PyMapping_Values(env);
3537 if (!keys || !vals)
3538 goto fail_2;
3539 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3540 PyErr_SetString(PyExc_TypeError,
3541 "spawnve(): env.keys() or env.values() is not a list");
3542 goto fail_2;
3543 }
Tim Peters5aa91602002-01-30 05:46:57 +00003544
Victor Stinnerd6f85422010-05-05 23:33:33 +00003545 for (pos = 0; pos < i; pos++) {
3546 char *p, *k, *v;
3547 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003548
Victor Stinnerd6f85422010-05-05 23:33:33 +00003549 key = PyList_GetItem(keys, pos);
3550 val = PyList_GetItem(vals, pos);
3551 if (!key || !val)
3552 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003553
Victor Stinnerd6f85422010-05-05 23:33:33 +00003554 if (!PyArg_Parse(
3555 key,
3556 "s;spawnve() arg 3 contains a non-string key",
3557 &k) ||
3558 !PyArg_Parse(
3559 val,
3560 "s;spawnve() arg 3 contains a non-string value",
3561 &v))
3562 {
3563 goto fail_2;
3564 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003565 /* Search from index 1 because on Windows starting '=' is allowed for
3566 defining hidden environment variables. */
3567 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3568 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3569 goto fail_2;
3570 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003571 len = PyString_Size(key) + PyString_Size(val) + 2;
3572 p = PyMem_NEW(char, len);
3573 if (p == NULL) {
3574 PyErr_NoMemory();
3575 goto fail_2;
3576 }
3577 PyOS_snprintf(p, len, "%s=%s", k, v);
3578 envlist[envc++] = p;
3579 }
3580 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003581
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003582#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003583 Py_BEGIN_ALLOW_THREADS
3584 spawnval = spawnve(mode, path, argvlist, envlist);
3585 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003586#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003587 if (mode == _OLD_P_OVERLAY)
3588 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003589
Victor Stinnerd6f85422010-05-05 23:33:33 +00003590 Py_BEGIN_ALLOW_THREADS
3591 spawnval = _spawnve(mode, path, argvlist, envlist);
3592 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003593#endif
Tim Peters25059d32001-12-07 20:35:43 +00003594
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 if (spawnval == -1)
3596 (void) posix_error();
3597 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003598#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003599 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003600#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003601 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003602#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003603
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003604 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003605 while (--envc >= 0)
3606 PyMem_DEL(envlist[envc]);
3607 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003608 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003609 free_string_array(argvlist, lastarg);
3610 Py_XDECREF(vals);
3611 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003612 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003613 PyMem_Free(path);
3614 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003615}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003616
3617/* OS/2 supports spawnvp & spawnvpe natively */
3618#if defined(PYOS_OS2)
3619PyDoc_STRVAR(posix_spawnvp__doc__,
3620"spawnvp(mode, file, args)\n\n\
3621Execute the program 'file' in a new process, using the environment\n\
3622search path to find the file.\n\
3623\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003624 mode: mode of process creation\n\
3625 file: executable file name\n\
3626 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003627
3628static PyObject *
3629posix_spawnvp(PyObject *self, PyObject *args)
3630{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003631 char *path;
3632 PyObject *argv;
3633 char **argvlist;
3634 int mode, i, argc;
3635 Py_intptr_t spawnval;
3636 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003637
Victor Stinnerd6f85422010-05-05 23:33:33 +00003638 /* spawnvp has three arguments: (mode, path, argv), where
3639 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003640
Victor Stinnerd6f85422010-05-05 23:33:33 +00003641 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3642 Py_FileSystemDefaultEncoding,
3643 &path, &argv))
3644 return NULL;
3645 if (PyList_Check(argv)) {
3646 argc = PyList_Size(argv);
3647 getitem = PyList_GetItem;
3648 }
3649 else if (PyTuple_Check(argv)) {
3650 argc = PyTuple_Size(argv);
3651 getitem = PyTuple_GetItem;
3652 }
3653 else {
3654 PyErr_SetString(PyExc_TypeError,
3655 "spawnvp() arg 2 must be a tuple or list");
3656 PyMem_Free(path);
3657 return NULL;
3658 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003659
Victor Stinnerd6f85422010-05-05 23:33:33 +00003660 argvlist = PyMem_NEW(char *, argc+1);
3661 if (argvlist == NULL) {
3662 PyMem_Free(path);
3663 return PyErr_NoMemory();
3664 }
3665 for (i = 0; i < argc; i++) {
3666 if (!PyArg_Parse((*getitem)(argv, i), "et",
3667 Py_FileSystemDefaultEncoding,
3668 &argvlist[i])) {
3669 free_string_array(argvlist, i);
3670 PyErr_SetString(
3671 PyExc_TypeError,
3672 "spawnvp() arg 2 must contain only strings");
3673 PyMem_Free(path);
3674 return NULL;
3675 }
3676 }
3677 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003678
Victor Stinnerd6f85422010-05-05 23:33:33 +00003679 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003680#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003681 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003682#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003683 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003684#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003685 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003686
Victor Stinnerd6f85422010-05-05 23:33:33 +00003687 free_string_array(argvlist, argc);
3688 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003689
Victor Stinnerd6f85422010-05-05 23:33:33 +00003690 if (spawnval == -1)
3691 return posix_error();
3692 else
3693 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003694}
3695
3696
3697PyDoc_STRVAR(posix_spawnvpe__doc__,
3698"spawnvpe(mode, file, args, env)\n\n\
3699Execute the program 'file' in a new process, using the environment\n\
3700search path to find the file.\n\
3701\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003702 mode: mode of process creation\n\
3703 file: executable file name\n\
3704 args: tuple or list of arguments\n\
3705 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003706
3707static PyObject *
3708posix_spawnvpe(PyObject *self, PyObject *args)
3709{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003710 char *path;
3711 PyObject *argv, *env;
3712 char **argvlist;
3713 char **envlist;
3714 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3715 int mode, i, pos, argc, envc;
3716 Py_intptr_t spawnval;
3717 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3718 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003719
Victor Stinnerd6f85422010-05-05 23:33:33 +00003720 /* spawnvpe has four arguments: (mode, path, argv, env), where
3721 argv is a list or tuple of strings and env is a dictionary
3722 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003723
Victor Stinnerd6f85422010-05-05 23:33:33 +00003724 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3725 Py_FileSystemDefaultEncoding,
3726 &path, &argv, &env))
3727 return NULL;
3728 if (PyList_Check(argv)) {
3729 argc = PyList_Size(argv);
3730 getitem = PyList_GetItem;
3731 }
3732 else if (PyTuple_Check(argv)) {
3733 argc = PyTuple_Size(argv);
3734 getitem = PyTuple_GetItem;
3735 }
3736 else {
3737 PyErr_SetString(PyExc_TypeError,
3738 "spawnvpe() arg 2 must be a tuple or list");
3739 goto fail_0;
3740 }
3741 if (!PyMapping_Check(env)) {
3742 PyErr_SetString(PyExc_TypeError,
3743 "spawnvpe() arg 3 must be a mapping object");
3744 goto fail_0;
3745 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003746
Victor Stinnerd6f85422010-05-05 23:33:33 +00003747 argvlist = PyMem_NEW(char *, argc+1);
3748 if (argvlist == NULL) {
3749 PyErr_NoMemory();
3750 goto fail_0;
3751 }
3752 for (i = 0; i < argc; i++) {
3753 if (!PyArg_Parse((*getitem)(argv, i),
3754 "et;spawnvpe() arg 2 must contain only strings",
3755 Py_FileSystemDefaultEncoding,
3756 &argvlist[i]))
3757 {
3758 lastarg = i;
3759 goto fail_1;
3760 }
3761 }
3762 lastarg = argc;
3763 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003764
Victor Stinnerd6f85422010-05-05 23:33:33 +00003765 i = PyMapping_Size(env);
3766 if (i < 0)
3767 goto fail_1;
3768 envlist = PyMem_NEW(char *, i + 1);
3769 if (envlist == NULL) {
3770 PyErr_NoMemory();
3771 goto fail_1;
3772 }
3773 envc = 0;
3774 keys = PyMapping_Keys(env);
3775 vals = PyMapping_Values(env);
3776 if (!keys || !vals)
3777 goto fail_2;
3778 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3779 PyErr_SetString(PyExc_TypeError,
3780 "spawnvpe(): env.keys() or env.values() is not a list");
3781 goto fail_2;
3782 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003783
Victor Stinnerd6f85422010-05-05 23:33:33 +00003784 for (pos = 0; pos < i; pos++) {
3785 char *p, *k, *v;
3786 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003787
Victor Stinnerd6f85422010-05-05 23:33:33 +00003788 key = PyList_GetItem(keys, pos);
3789 val = PyList_GetItem(vals, pos);
3790 if (!key || !val)
3791 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003792
Victor Stinnerd6f85422010-05-05 23:33:33 +00003793 if (!PyArg_Parse(
3794 key,
3795 "s;spawnvpe() arg 3 contains a non-string key",
3796 &k) ||
3797 !PyArg_Parse(
3798 val,
3799 "s;spawnvpe() arg 3 contains a non-string value",
3800 &v))
3801 {
3802 goto fail_2;
3803 }
Serhiy Storchaka787826c2017-06-25 09:50:00 +03003804 /* Search from index 1 because on Windows starting '=' is allowed for
3805 defining hidden environment variables. */
3806 if (*k == '\0' || strchr(k + 1, '=') != NULL) {
3807 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
3808 goto fail_2;
3809 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003810 len = PyString_Size(key) + PyString_Size(val) + 2;
3811 p = PyMem_NEW(char, len);
3812 if (p == NULL) {
3813 PyErr_NoMemory();
3814 goto fail_2;
3815 }
3816 PyOS_snprintf(p, len, "%s=%s", k, v);
3817 envlist[envc++] = p;
3818 }
3819 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003820
Victor Stinnerd6f85422010-05-05 23:33:33 +00003821 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003822#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003823 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003824#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003825 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003826#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003827 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003828
Victor Stinnerd6f85422010-05-05 23:33:33 +00003829 if (spawnval == -1)
3830 (void) posix_error();
3831 else
3832 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003833
3834 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003835 while (--envc >= 0)
3836 PyMem_DEL(envlist[envc]);
3837 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003838 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003839 free_string_array(argvlist, lastarg);
3840 Py_XDECREF(vals);
3841 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003842 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003843 PyMem_Free(path);
3844 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003845}
3846#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003847#endif /* HAVE_SPAWNV */
3848
3849
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003850#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003851PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003852"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003853Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3854\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003855Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003856
3857static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003858posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003859{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003860 pid_t pid;
3861 int result = 0;
3862 _PyImport_AcquireLock();
3863 pid = fork1();
3864 if (pid == 0) {
3865 /* child: this clobbers and resets the import lock. */
3866 PyOS_AfterFork();
3867 } else {
3868 /* parent: release the import lock. */
3869 result = _PyImport_ReleaseLock();
3870 }
3871 if (pid == -1)
3872 return posix_error();
3873 if (result < 0) {
3874 /* Don't clobber the OSError if the fork failed. */
3875 PyErr_SetString(PyExc_RuntimeError,
3876 "not holding the import lock");
3877 return NULL;
3878 }
3879 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003880}
3881#endif
3882
3883
Guido van Rossumad0ee831995-03-01 10:34:45 +00003884#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003885PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003886"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003889
Barry Warsaw53699e91996-12-10 23:23:01 +00003890static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003891posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003892{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003893 pid_t pid;
3894 int result = 0;
3895 _PyImport_AcquireLock();
3896 pid = fork();
3897 if (pid == 0) {
3898 /* child: this clobbers and resets the import lock. */
3899 PyOS_AfterFork();
3900 } else {
3901 /* parent: release the import lock. */
3902 result = _PyImport_ReleaseLock();
3903 }
3904 if (pid == -1)
3905 return posix_error();
3906 if (result < 0) {
3907 /* Don't clobber the OSError if the fork failed. */
3908 PyErr_SetString(PyExc_RuntimeError,
3909 "not holding the import lock");
3910 return NULL;
3911 }
3912 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003913}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003914#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003915
Neal Norwitzb59798b2003-03-21 01:43:31 +00003916/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003917/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3918#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003919#define DEV_PTY_FILE "/dev/ptc"
3920#define HAVE_DEV_PTMX
3921#else
3922#define DEV_PTY_FILE "/dev/ptmx"
3923#endif
3924
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003925#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003926#ifdef HAVE_PTY_H
3927#include <pty.h>
3928#else
3929#ifdef HAVE_LIBUTIL_H
3930#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003931#else
3932#ifdef HAVE_UTIL_H
3933#include <util.h>
3934#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003935#endif /* HAVE_LIBUTIL_H */
3936#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003937#ifdef HAVE_STROPTS_H
3938#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003939#endif
Miss Islington (bot)836b6422018-02-14 12:43:17 -08003940#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003941
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003942#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003943PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003944"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003945Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003946
3947static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003948posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003949{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003950 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003951#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003952 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003953#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003954#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003955 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003956#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003957 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003958#endif
3959#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003960
Thomas Wouters70c21a12000-07-14 14:28:33 +00003961#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003962 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3963 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003964#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003965 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3966 if (slave_name == NULL)
3967 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003968
Victor Stinnerd6f85422010-05-05 23:33:33 +00003969 slave_fd = open(slave_name, O_RDWR);
3970 if (slave_fd < 0)
3971 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003972#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003973 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3974 if (master_fd < 0)
3975 return posix_error();
3976 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3977 /* change permission of slave */
3978 if (grantpt(master_fd) < 0) {
3979 PyOS_setsig(SIGCHLD, sig_saved);
3980 return posix_error();
3981 }
3982 /* unlock slave */
3983 if (unlockpt(master_fd) < 0) {
3984 PyOS_setsig(SIGCHLD, sig_saved);
3985 return posix_error();
3986 }
3987 PyOS_setsig(SIGCHLD, sig_saved);
3988 slave_name = ptsname(master_fd); /* get name of slave */
3989 if (slave_name == NULL)
3990 return posix_error();
3991 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3992 if (slave_fd < 0)
3993 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003994#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003995 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3996 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003997#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003998 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003999#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004000#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00004001#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00004002
Victor Stinnerd6f85422010-05-05 23:33:33 +00004003 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00004004
Fred Drake8cef4cf2000-06-28 16:40:38 +00004005}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00004006#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00004007
4008#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00004011Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
4012Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004013To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00004014
4015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004016posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00004017{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004018 int master_fd = -1, result = 0;
4019 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00004020
Victor Stinnerd6f85422010-05-05 23:33:33 +00004021 _PyImport_AcquireLock();
4022 pid = forkpty(&master_fd, NULL, NULL, NULL);
4023 if (pid == 0) {
4024 /* child: this clobbers and resets the import lock. */
4025 PyOS_AfterFork();
4026 } else {
4027 /* parent: release the import lock. */
4028 result = _PyImport_ReleaseLock();
4029 }
4030 if (pid == -1)
4031 return posix_error();
4032 if (result < 0) {
4033 /* Don't clobber the OSError if the fork failed. */
4034 PyErr_SetString(PyExc_RuntimeError,
4035 "not holding the import lock");
4036 return NULL;
4037 }
4038 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00004039}
4040#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004041
Guido van Rossumad0ee831995-03-01 10:34:45 +00004042#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004043PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004044"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004046
Barry Warsaw53699e91996-12-10 23:23:01 +00004047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004048posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004049{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004050 return _PyInt_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004051}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004052#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Guido van Rossumad0ee831995-03-01 10:34:45 +00004055#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004059
Barry Warsaw53699e91996-12-10 23:23:01 +00004060static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004061posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004062{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004063 return _PyInt_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004064}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004065#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004067
Guido van Rossumad0ee831995-03-01 10:34:45 +00004068#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004070"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004071Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004072
Barry Warsaw53699e91996-12-10 23:23:01 +00004073static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004074posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004075{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004076 return _PyInt_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004077}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004078#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004081PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004082"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004083Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004084
Barry Warsaw53699e91996-12-10 23:23:01 +00004085static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004086posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004087{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004088 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004089}
4090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004091
Fred Drakec9680921999-12-13 16:37:25 +00004092#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004093PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004094"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004095Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00004096
4097static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004098posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00004099{
4100 PyObject *result = NULL;
4101
Fred Drakec9680921999-12-13 16:37:25 +00004102#ifdef NGROUPS_MAX
4103#define MAX_GROUPS NGROUPS_MAX
4104#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004105 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00004106#define MAX_GROUPS 64
4107#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004108 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004109
Victor Stinner59729ff2011-07-05 11:28:19 +02004110 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004111 * This is a helper variable to store the intermediate result when
4112 * that happens.
4113 *
4114 * To keep the code readable the OSX behaviour is unconditional,
4115 * according to the POSIX spec this should be safe on all unix-y
4116 * systems.
4117 */
4118 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004119 int n;
Fred Drakec9680921999-12-13 16:37:25 +00004120
Ned Deily80743642013-08-01 21:19:09 -07004121#ifdef __APPLE__
4122 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
4123 * there are more groups than can fit in grouplist. Therefore, on OS X
4124 * always first call getgroups with length 0 to get the actual number
4125 * of groups.
4126 */
4127 n = getgroups(0, NULL);
4128 if (n < 0) {
4129 return posix_error();
4130 } else if (n <= MAX_GROUPS) {
4131 /* groups will fit in existing array */
4132 alt_grouplist = grouplist;
4133 } else {
4134 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4135 if (alt_grouplist == NULL) {
4136 errno = EINVAL;
4137 return posix_error();
4138 }
4139 }
4140
4141 n = getgroups(n, alt_grouplist);
4142 if (n == -1) {
4143 if (alt_grouplist != grouplist) {
4144 PyMem_Free(alt_grouplist);
4145 }
4146 return posix_error();
4147 }
4148#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004149 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004150 if (n < 0) {
4151 if (errno == EINVAL) {
4152 n = getgroups(0, NULL);
4153 if (n == -1) {
4154 return posix_error();
4155 }
4156 if (n == 0) {
4157 /* Avoid malloc(0) */
4158 alt_grouplist = grouplist;
4159 } else {
4160 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
4161 if (alt_grouplist == NULL) {
4162 errno = EINVAL;
4163 return posix_error();
4164 }
4165 n = getgroups(n, alt_grouplist);
4166 if (n == -1) {
4167 PyMem_Free(alt_grouplist);
4168 return posix_error();
4169 }
4170 }
4171 } else {
4172 return posix_error();
4173 }
4174 }
Ned Deily80743642013-08-01 21:19:09 -07004175#endif
4176
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004177 result = PyList_New(n);
4178 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00004179 int i;
4180 for (i = 0; i < n; ++i) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004181 PyObject *o = _PyInt_FromGid(alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004182 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00004183 Py_DECREF(result);
4184 result = NULL;
4185 break;
Fred Drakec9680921999-12-13 16:37:25 +00004186 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00004187 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00004188 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00004189 }
4190
4191 if (alt_grouplist != grouplist) {
4192 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00004193 }
Neal Norwitze241ce82003-02-17 18:17:05 +00004194
Fred Drakec9680921999-12-13 16:37:25 +00004195 return result;
4196}
4197#endif
4198
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004199#ifdef HAVE_INITGROUPS
4200PyDoc_STRVAR(posix_initgroups__doc__,
4201"initgroups(username, gid) -> None\n\n\
4202Call the system initgroups() to initialize the group access list with all of\n\
4203the groups of which the specified username is a member, plus the specified\n\
4204group id.");
4205
4206static PyObject *
4207posix_initgroups(PyObject *self, PyObject *args)
4208{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004209 char *username;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004210#ifdef __APPLE__
4211 int gid;
4212#else
4213 gid_t gid;
4214#endif
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004215
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004216#ifdef __APPLE__
4217 if (!PyArg_ParseTuple(args, "si:initgroups", &username,
4218 &gid))
4219#else
4220 if (!PyArg_ParseTuple(args, "sO&:initgroups", &username,
4221 _Py_Gid_Converter, &gid))
4222#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004223 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004224
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004225 if (initgroups(username, gid) == -1)
Victor Stinnerd6f85422010-05-05 23:33:33 +00004226 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004227
Victor Stinnerd6f85422010-05-05 23:33:33 +00004228 Py_INCREF(Py_None);
4229 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00004230}
4231#endif
4232
Martin v. Löwis606edc12002-06-13 21:09:11 +00004233#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004234PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004235"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00004236Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00004237
4238static PyObject *
4239posix_getpgid(PyObject *self, PyObject *args)
4240{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004241 pid_t pid, pgid;
4242 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
4243 return NULL;
4244 pgid = getpgid(pid);
4245 if (pgid < 0)
4246 return posix_error();
4247 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004248}
4249#endif /* HAVE_GETPGID */
4250
4251
Guido van Rossumb6775db1994-08-01 11:34:53 +00004252#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004253PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004254"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004255Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Barry Warsaw53699e91996-12-10 23:23:01 +00004257static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004258posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004259{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004261 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004262#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004263 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004264#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004265}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004266#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Guido van Rossumb6775db1994-08-01 11:34:53 +00004269#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004270PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004271"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004272Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004273
Barry Warsaw53699e91996-12-10 23:23:01 +00004274static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004275posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004276{
Guido van Rossum64933891994-10-20 21:56:42 +00004277#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004278 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004279#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004280 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004281#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004282 return posix_error();
4283 Py_INCREF(Py_None);
4284 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004285}
4286
Guido van Rossumb6775db1994-08-01 11:34:53 +00004287#endif /* HAVE_SETPGRP */
4288
Guido van Rossumad0ee831995-03-01 10:34:45 +00004289#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004290PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004291"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004292Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293
Barry Warsaw53699e91996-12-10 23:23:01 +00004294static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004295posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004296{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004297 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004298}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004299#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Fred Drake12c6e2d1999-12-14 21:25:03 +00004302#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004303PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004304"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004306
4307static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004308posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004309{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004310 PyObject *result = NULL;
4311 char *name;
4312 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004313
Victor Stinnerd6f85422010-05-05 23:33:33 +00004314 errno = 0;
4315 name = getlogin();
4316 if (name == NULL) {
4317 if (errno)
4318 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004319 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004320 PyErr_SetString(PyExc_OSError,
4321 "unable to determine login name");
4322 }
4323 else
4324 result = PyString_FromString(name);
4325 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004326
Fred Drake12c6e2d1999-12-14 21:25:03 +00004327 return result;
4328}
4329#endif
4330
Guido van Rossumad0ee831995-03-01 10:34:45 +00004331#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004332PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004333"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004334Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004335
Barry Warsaw53699e91996-12-10 23:23:01 +00004336static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004337posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004338{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02004339 return _PyInt_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004340}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004341#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004343
Guido van Rossumad0ee831995-03-01 10:34:45 +00004344#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004345PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004346"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004347Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004348
Barry Warsaw53699e91996-12-10 23:23:01 +00004349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004350posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004351{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004352 pid_t pid;
4353 int sig;
4354 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4355 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004356#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004357 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4358 APIRET rc;
4359 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004360 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004361
4362 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4363 APIRET rc;
4364 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004365 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004366
4367 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004368 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004369#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004370 if (kill(pid, sig) == -1)
4371 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004372#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004373 Py_INCREF(Py_None);
4374 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004375}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004376#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004377
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004378#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004379PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004380"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004381Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004382
4383static PyObject *
4384posix_killpg(PyObject *self, PyObject *args)
4385{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004386 int sig;
4387 pid_t pgid;
4388 /* XXX some man pages make the `pgid` parameter an int, others
4389 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4390 take the same type. Moreover, pid_t is always at least as wide as
4391 int (else compilation of this module fails), which is safe. */
4392 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4393 return NULL;
4394 if (killpg(pgid, sig) == -1)
4395 return posix_error();
4396 Py_INCREF(Py_None);
4397 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004398}
4399#endif
4400
Brian Curtine5aa8862010-04-02 23:26:06 +00004401#ifdef MS_WINDOWS
4402PyDoc_STRVAR(win32_kill__doc__,
4403"kill(pid, sig)\n\n\
4404Kill a process with a signal.");
4405
4406static PyObject *
4407win32_kill(PyObject *self, PyObject *args)
4408{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004409 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004410 DWORD pid, sig, err;
4411 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004412
Victor Stinnerd6f85422010-05-05 23:33:33 +00004413 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4414 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004415
Victor Stinnerd6f85422010-05-05 23:33:33 +00004416 /* Console processes which share a common console can be sent CTRL+C or
4417 CTRL+BREAK events, provided they handle said events. */
4418 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4419 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4420 err = GetLastError();
4421 return PyErr_SetFromWindowsErr(err);
4422 }
4423 else
4424 Py_RETURN_NONE;
4425 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004426
Victor Stinnerd6f85422010-05-05 23:33:33 +00004427 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4428 attempt to open and terminate the process. */
4429 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4430 if (handle == NULL) {
4431 err = GetLastError();
4432 return PyErr_SetFromWindowsErr(err);
4433 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004434
Victor Stinnerd6f85422010-05-05 23:33:33 +00004435 if (TerminateProcess(handle, sig) == 0) {
4436 err = GetLastError();
4437 result = PyErr_SetFromWindowsErr(err);
4438 } else {
4439 Py_INCREF(Py_None);
4440 result = Py_None;
4441 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004442
Victor Stinnerd6f85422010-05-05 23:33:33 +00004443 CloseHandle(handle);
4444 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004445}
Brian Curtincaea7e82011-06-08 19:29:53 -05004446
Brian Curtin5446f082011-06-09 10:00:42 -05004447PyDoc_STRVAR(posix__isdir__doc__,
4448"Return true if the pathname refers to an existing directory.");
4449
Brian Curtincaea7e82011-06-08 19:29:53 -05004450static PyObject *
4451posix__isdir(PyObject *self, PyObject *args)
4452{
Brian Curtincaea7e82011-06-08 19:29:53 -05004453 char *path;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004454 Py_UNICODE *wpath;
Brian Curtincaea7e82011-06-08 19:29:53 -05004455 DWORD attributes;
4456
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03004457 if (PyArg_ParseTuple(args, "u|:_isdir", &wpath)) {
Brian Curtincaea7e82011-06-08 19:29:53 -05004458 attributes = GetFileAttributesW(wpath);
4459 if (attributes == INVALID_FILE_ATTRIBUTES)
4460 Py_RETURN_FALSE;
4461 goto check;
4462 }
4463 /* Drop the argument parsing error as narrow strings
4464 are also valid. */
4465 PyErr_Clear();
4466
4467 if (!PyArg_ParseTuple(args, "et:_isdir",
4468 Py_FileSystemDefaultEncoding, &path))
4469 return NULL;
4470
4471 attributes = GetFileAttributesA(path);
Serhiy Storchaka46f5b352013-01-28 20:19:50 +02004472 PyMem_Free(path);
Brian Curtincaea7e82011-06-08 19:29:53 -05004473 if (attributes == INVALID_FILE_ATTRIBUTES)
4474 Py_RETURN_FALSE;
4475
4476check:
4477 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4478 Py_RETURN_TRUE;
4479 else
4480 Py_RETURN_FALSE;
4481}
Brian Curtine5aa8862010-04-02 23:26:06 +00004482#endif /* MS_WINDOWS */
4483
Guido van Rossumc0125471996-06-28 18:55:32 +00004484#ifdef HAVE_PLOCK
4485
4486#ifdef HAVE_SYS_LOCK_H
4487#include <sys/lock.h>
4488#endif
4489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004491"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004492Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004493
Barry Warsaw53699e91996-12-10 23:23:01 +00004494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004495posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004496{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004497 int op;
4498 if (!PyArg_ParseTuple(args, "i:plock", &op))
4499 return NULL;
4500 if (plock(op) == -1)
4501 return posix_error();
4502 Py_INCREF(Py_None);
4503 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004504}
4505#endif
4506
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004507
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004508#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004509PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004510"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004511Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004512
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004513#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004514#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004515static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004516async_system(const char *command)
4517{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004518 char errormsg[256], args[1024];
4519 RESULTCODES rcodes;
4520 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004521
Victor Stinnerd6f85422010-05-05 23:33:33 +00004522 char *shell = getenv("COMSPEC");
4523 if (!shell)
4524 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004525
Victor Stinnerd6f85422010-05-05 23:33:33 +00004526 /* avoid overflowing the argument buffer */
4527 if (strlen(shell) + 3 + strlen(command) >= 1024)
4528 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004529
Victor Stinnerd6f85422010-05-05 23:33:33 +00004530 args[0] = '\0';
4531 strcat(args, shell);
4532 strcat(args, "/c ");
4533 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004534
Victor Stinnerd6f85422010-05-05 23:33:33 +00004535 /* execute asynchronously, inheriting the environment */
4536 rc = DosExecPgm(errormsg,
4537 sizeof(errormsg),
4538 EXEC_ASYNC,
4539 args,
4540 NULL,
4541 &rcodes,
4542 shell);
4543 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004544}
4545
Guido van Rossumd48f2521997-12-05 22:19:34 +00004546static FILE *
4547popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004548{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004549 int oldfd, tgtfd;
4550 HFILE pipeh[2];
4551 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004552
Victor Stinnerd6f85422010-05-05 23:33:33 +00004553 /* mode determines which of stdin or stdout is reconnected to
4554 * the pipe to the child
4555 */
4556 if (strchr(mode, 'r') != NULL) {
4557 tgt_fd = 1; /* stdout */
4558 } else if (strchr(mode, 'w')) {
4559 tgt_fd = 0; /* stdin */
4560 } else {
4561 *err = ERROR_INVALID_ACCESS;
4562 return NULL;
4563 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004564
Victor Stinnerd6f85422010-05-05 23:33:33 +00004565 /* setup the pipe */
4566 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4567 *err = rc;
4568 return NULL;
4569 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004570
Victor Stinnerd6f85422010-05-05 23:33:33 +00004571 /* prevent other threads accessing stdio */
4572 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004573
Victor Stinnerd6f85422010-05-05 23:33:33 +00004574 /* reconnect stdio and execute child */
4575 oldfd = dup(tgtfd);
4576 close(tgtfd);
4577 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4578 DosClose(pipeh[tgtfd]);
4579 rc = async_system(command);
4580 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004581
Victor Stinnerd6f85422010-05-05 23:33:33 +00004582 /* restore stdio */
4583 dup2(oldfd, tgtfd);
4584 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004585
Victor Stinnerd6f85422010-05-05 23:33:33 +00004586 /* allow other threads access to stdio */
4587 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004588
Victor Stinnerd6f85422010-05-05 23:33:33 +00004589 /* if execution of child was successful return file stream */
4590 if (rc == NO_ERROR)
4591 return fdopen(pipeh[1 - tgtfd], mode);
4592 else {
4593 DosClose(pipeh[1 - tgtfd]);
4594 *err = rc;
4595 return NULL;
4596 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004597}
4598
4599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004600posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004601{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004602 char *name;
4603 char *mode = "r";
4604 int err, bufsize = -1;
4605 FILE *fp;
4606 PyObject *f;
4607 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4608 return NULL;
4609 Py_BEGIN_ALLOW_THREADS
4610 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4611 Py_END_ALLOW_THREADS
4612 if (fp == NULL)
4613 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004614
Victor Stinnerd6f85422010-05-05 23:33:33 +00004615 f = PyFile_FromFile(fp, name, mode, fclose);
4616 if (f != NULL)
4617 PyFile_SetBufSize(f, bufsize);
4618 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004619}
4620
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004621#elif defined(PYCC_GCC)
4622
4623/* standard posix version of popen() support */
4624static PyObject *
4625posix_popen(PyObject *self, PyObject *args)
4626{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004627 char *name;
4628 char *mode = "r";
4629 int bufsize = -1;
4630 FILE *fp;
4631 PyObject *f;
4632 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4633 return NULL;
4634 Py_BEGIN_ALLOW_THREADS
4635 fp = popen(name, mode);
4636 Py_END_ALLOW_THREADS
4637 if (fp == NULL)
4638 return posix_error();
4639 f = PyFile_FromFile(fp, name, mode, pclose);
4640 if (f != NULL)
4641 PyFile_SetBufSize(f, bufsize);
4642 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004643}
4644
4645/* fork() under OS/2 has lots'o'warts
4646 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4647 * most of this code is a ripoff of the win32 code, but using the
4648 * capabilities of EMX's C library routines
4649 */
4650
4651/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4652#define POPEN_1 1
4653#define POPEN_2 2
4654#define POPEN_3 3
4655#define POPEN_4 4
4656
4657static PyObject *_PyPopen(char *, int, int, int);
4658static int _PyPclose(FILE *file);
4659
4660/*
4661 * Internal dictionary mapping popen* file pointers to process handles,
4662 * for use when retrieving the process exit code. See _PyPclose() below
4663 * for more information on this dictionary's use.
4664 */
4665static PyObject *_PyPopenProcs = NULL;
4666
4667/* os2emx version of popen2()
4668 *
4669 * The result of this function is a pipe (file) connected to the
4670 * process's stdin, and a pipe connected to the process's stdout.
4671 */
4672
4673static PyObject *
4674os2emx_popen2(PyObject *self, PyObject *args)
4675{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004676 PyObject *f;
4677 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004678
Victor Stinnerd6f85422010-05-05 23:33:33 +00004679 char *cmdstring;
4680 char *mode = "t";
4681 int bufsize = -1;
4682 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4683 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004684
Victor Stinnerd6f85422010-05-05 23:33:33 +00004685 if (*mode == 't')
4686 tm = O_TEXT;
4687 else if (*mode != 'b') {
4688 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4689 return NULL;
4690 } else
4691 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004692
Victor Stinnerd6f85422010-05-05 23:33:33 +00004693 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004694
Victor Stinnerd6f85422010-05-05 23:33:33 +00004695 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004696}
4697
4698/*
4699 * Variation on os2emx.popen2
4700 *
4701 * The result of this function is 3 pipes - the process's stdin,
4702 * stdout and stderr
4703 */
4704
4705static PyObject *
4706os2emx_popen3(PyObject *self, PyObject *args)
4707{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004708 PyObject *f;
4709 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004710
Victor Stinnerd6f85422010-05-05 23:33:33 +00004711 char *cmdstring;
4712 char *mode = "t";
4713 int bufsize = -1;
4714 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4715 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004716
Victor Stinnerd6f85422010-05-05 23:33:33 +00004717 if (*mode == 't')
4718 tm = O_TEXT;
4719 else if (*mode != 'b') {
4720 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4721 return NULL;
4722 } else
4723 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004724
Victor Stinnerd6f85422010-05-05 23:33:33 +00004725 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726
Victor Stinnerd6f85422010-05-05 23:33:33 +00004727 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004728}
4729
4730/*
4731 * Variation on os2emx.popen2
4732 *
Tim Peters11b23062003-04-23 02:39:17 +00004733 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004734 * and stdout+stderr combined as a single pipe.
4735 */
4736
4737static PyObject *
4738os2emx_popen4(PyObject *self, PyObject *args)
4739{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004740 PyObject *f;
4741 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004742
Victor Stinnerd6f85422010-05-05 23:33:33 +00004743 char *cmdstring;
4744 char *mode = "t";
4745 int bufsize = -1;
4746 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4747 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004748
Victor Stinnerd6f85422010-05-05 23:33:33 +00004749 if (*mode == 't')
4750 tm = O_TEXT;
4751 else if (*mode != 'b') {
4752 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4753 return NULL;
4754 } else
4755 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004756
Victor Stinnerd6f85422010-05-05 23:33:33 +00004757 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004758
Victor Stinnerd6f85422010-05-05 23:33:33 +00004759 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004760}
4761
4762/* a couple of structures for convenient handling of multiple
4763 * file handles and pipes
4764 */
4765struct file_ref
4766{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004767 int handle;
4768 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004769};
4770
4771struct pipe_ref
4772{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004773 int rd;
4774 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004775};
4776
4777/* The following code is derived from the win32 code */
4778
4779static PyObject *
4780_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4781{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004782 struct file_ref stdio[3];
4783 struct pipe_ref p_fd[3];
4784 FILE *p_s[3];
4785 int file_count, i, pipe_err;
4786 pid_t pipe_pid;
4787 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4788 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004789
Victor Stinnerd6f85422010-05-05 23:33:33 +00004790 /* file modes for subsequent fdopen's on pipe handles */
4791 if (mode == O_TEXT)
4792 {
4793 rd_mode = "rt";
4794 wr_mode = "wt";
4795 }
4796 else
4797 {
4798 rd_mode = "rb";
4799 wr_mode = "wb";
4800 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004801
Victor Stinnerd6f85422010-05-05 23:33:33 +00004802 /* prepare shell references */
4803 if ((shell = getenv("EMXSHELL")) == NULL)
4804 if ((shell = getenv("COMSPEC")) == NULL)
4805 {
4806 errno = ENOENT;
4807 return posix_error();
4808 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004809
Victor Stinnerd6f85422010-05-05 23:33:33 +00004810 sh_name = _getname(shell);
4811 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4812 opt = "/c";
4813 else
4814 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004815
Victor Stinnerd6f85422010-05-05 23:33:33 +00004816 /* save current stdio fds + their flags, and set not inheritable */
4817 i = pipe_err = 0;
4818 while (pipe_err >= 0 && i < 3)
4819 {
4820 pipe_err = stdio[i].handle = dup(i);
4821 stdio[i].flags = fcntl(i, F_GETFD, 0);
4822 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4823 i++;
4824 }
4825 if (pipe_err < 0)
4826 {
4827 /* didn't get them all saved - clean up and bail out */
4828 int saved_err = errno;
4829 while (i-- > 0)
4830 {
4831 close(stdio[i].handle);
4832 }
4833 errno = saved_err;
4834 return posix_error();
4835 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004836
Victor Stinnerd6f85422010-05-05 23:33:33 +00004837 /* create pipe ends */
4838 file_count = 2;
4839 if (n == POPEN_3)
4840 file_count = 3;
4841 i = pipe_err = 0;
4842 while ((pipe_err == 0) && (i < file_count))
4843 pipe_err = pipe((int *)&p_fd[i++]);
4844 if (pipe_err < 0)
4845 {
4846 /* didn't get them all made - clean up and bail out */
4847 while (i-- > 0)
4848 {
4849 close(p_fd[i].wr);
4850 close(p_fd[i].rd);
4851 }
4852 errno = EPIPE;
4853 return posix_error();
4854 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004855
Victor Stinnerd6f85422010-05-05 23:33:33 +00004856 /* change the actual standard IO streams over temporarily,
4857 * making the retained pipe ends non-inheritable
4858 */
4859 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004860
Victor Stinnerd6f85422010-05-05 23:33:33 +00004861 /* - stdin */
4862 if (dup2(p_fd[0].rd, 0) == 0)
4863 {
4864 close(p_fd[0].rd);
4865 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4866 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4867 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4868 {
4869 close(p_fd[0].wr);
4870 pipe_err = -1;
4871 }
4872 }
4873 else
4874 {
4875 pipe_err = -1;
4876 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004877
Victor Stinnerd6f85422010-05-05 23:33:33 +00004878 /* - stdout */
4879 if (pipe_err == 0)
4880 {
4881 if (dup2(p_fd[1].wr, 1) == 1)
4882 {
4883 close(p_fd[1].wr);
4884 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4885 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4886 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4887 {
4888 close(p_fd[1].rd);
4889 pipe_err = -1;
4890 }
4891 }
4892 else
4893 {
4894 pipe_err = -1;
4895 }
4896 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004897
Victor Stinnerd6f85422010-05-05 23:33:33 +00004898 /* - stderr, as required */
4899 if (pipe_err == 0)
4900 switch (n)
4901 {
4902 case POPEN_3:
4903 {
4904 if (dup2(p_fd[2].wr, 2) == 2)
4905 {
4906 close(p_fd[2].wr);
4907 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4908 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4909 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4910 {
4911 close(p_fd[2].rd);
4912 pipe_err = -1;
4913 }
4914 }
4915 else
4916 {
4917 pipe_err = -1;
4918 }
4919 break;
4920 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004921
Victor Stinnerd6f85422010-05-05 23:33:33 +00004922 case POPEN_4:
4923 {
4924 if (dup2(1, 2) != 2)
4925 {
4926 pipe_err = -1;
4927 }
4928 break;
4929 }
4930 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004931
Victor Stinnerd6f85422010-05-05 23:33:33 +00004932 /* spawn the child process */
4933 if (pipe_err == 0)
4934 {
4935 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4936 if (pipe_pid == -1)
4937 {
4938 pipe_err = -1;
4939 }
4940 else
4941 {
4942 /* save the PID into the FILE structure
4943 * NOTE: this implementation doesn't actually
4944 * take advantage of this, but do it for
4945 * completeness - AIM Apr01
4946 */
4947 for (i = 0; i < file_count; i++)
4948 p_s[i]->_pid = pipe_pid;
4949 }
4950 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004951
Victor Stinnerd6f85422010-05-05 23:33:33 +00004952 /* reset standard IO to normal */
4953 for (i = 0; i < 3; i++)
4954 {
4955 dup2(stdio[i].handle, i);
4956 fcntl(i, F_SETFD, stdio[i].flags);
4957 close(stdio[i].handle);
4958 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004959
Victor Stinnerd6f85422010-05-05 23:33:33 +00004960 /* if any remnant problems, clean up and bail out */
4961 if (pipe_err < 0)
4962 {
4963 for (i = 0; i < 3; i++)
4964 {
4965 close(p_fd[i].rd);
4966 close(p_fd[i].wr);
4967 }
4968 errno = EPIPE;
4969 return posix_error_with_filename(cmdstring);
4970 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004971
Victor Stinnerd6f85422010-05-05 23:33:33 +00004972 /* build tuple of file objects to return */
4973 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4974 PyFile_SetBufSize(p_f[0], bufsize);
4975 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4976 PyFile_SetBufSize(p_f[1], bufsize);
4977 if (n == POPEN_3)
4978 {
4979 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4980 PyFile_SetBufSize(p_f[0], bufsize);
4981 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4982 }
4983 else
4984 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004985
Victor Stinnerd6f85422010-05-05 23:33:33 +00004986 /*
4987 * Insert the files we've created into the process dictionary
4988 * all referencing the list with the process handle and the
4989 * initial number of files (see description below in _PyPclose).
4990 * Since if _PyPclose later tried to wait on a process when all
4991 * handles weren't closed, it could create a deadlock with the
4992 * child, we spend some energy here to try to ensure that we
4993 * either insert all file handles into the dictionary or none
4994 * at all. It's a little clumsy with the various popen modes
4995 * and variable number of files involved.
4996 */
4997 if (!_PyPopenProcs)
4998 {
4999 _PyPopenProcs = PyDict_New();
5000 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005001
Victor Stinnerd6f85422010-05-05 23:33:33 +00005002 if (_PyPopenProcs)
5003 {
5004 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
5005 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005006
Victor Stinnerd6f85422010-05-05 23:33:33 +00005007 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5008 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005009
Victor Stinnerd6f85422010-05-05 23:33:33 +00005010 procObj = PyList_New(2);
5011 pidObj = PyLong_FromPid(pipe_pid);
5012 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005013
Victor Stinnerd6f85422010-05-05 23:33:33 +00005014 if (procObj && pidObj && intObj)
5015 {
5016 PyList_SetItem(procObj, 0, pidObj);
5017 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005018
Victor Stinnerd6f85422010-05-05 23:33:33 +00005019 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
5020 if (fileObj[0])
5021 {
5022 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5023 fileObj[0],
5024 procObj);
5025 }
5026 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
5027 if (fileObj[1])
5028 {
5029 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5030 fileObj[1],
5031 procObj);
5032 }
5033 if (file_count >= 3)
5034 {
5035 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
5036 if (fileObj[2])
5037 {
5038 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5039 fileObj[2],
5040 procObj);
5041 }
5042 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005043
Victor Stinnerd6f85422010-05-05 23:33:33 +00005044 if (ins_rc[0] < 0 || !fileObj[0] ||
5045 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5046 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
5047 {
5048 /* Something failed - remove any dictionary
5049 * entries that did make it.
5050 */
5051 if (!ins_rc[0] && fileObj[0])
5052 {
5053 PyDict_DelItem(_PyPopenProcs,
5054 fileObj[0]);
5055 }
5056 if (!ins_rc[1] && fileObj[1])
5057 {
5058 PyDict_DelItem(_PyPopenProcs,
5059 fileObj[1]);
5060 }
5061 if (!ins_rc[2] && fileObj[2])
5062 {
5063 PyDict_DelItem(_PyPopenProcs,
5064 fileObj[2]);
5065 }
5066 }
5067 }
Tim Peters11b23062003-04-23 02:39:17 +00005068
Victor Stinnerd6f85422010-05-05 23:33:33 +00005069 /*
5070 * Clean up our localized references for the dictionary keys
5071 * and value since PyDict_SetItem will Py_INCREF any copies
5072 * that got placed in the dictionary.
5073 */
5074 Py_XDECREF(procObj);
5075 Py_XDECREF(fileObj[0]);
5076 Py_XDECREF(fileObj[1]);
5077 Py_XDECREF(fileObj[2]);
5078 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005079
Victor Stinnerd6f85422010-05-05 23:33:33 +00005080 /* Child is launched. */
5081 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005082}
5083
5084/*
5085 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5086 * exit code for the child process and return as a result of the close.
5087 *
5088 * This function uses the _PyPopenProcs dictionary in order to map the
5089 * input file pointer to information about the process that was
5090 * originally created by the popen* call that created the file pointer.
5091 * The dictionary uses the file pointer as a key (with one entry
5092 * inserted for each file returned by the original popen* call) and a
5093 * single list object as the value for all files from a single call.
5094 * The list object contains the Win32 process handle at [0], and a file
5095 * count at [1], which is initialized to the total number of file
5096 * handles using that list.
5097 *
5098 * This function closes whichever handle it is passed, and decrements
5099 * the file count in the dictionary for the process handle pointed to
5100 * by this file. On the last close (when the file count reaches zero),
5101 * this function will wait for the child process and then return its
5102 * exit code as the result of the close() operation. This permits the
5103 * files to be closed in any order - it is always the close() of the
5104 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00005105 *
5106 * NOTE: This function is currently called with the GIL released.
5107 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005108 */
5109
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005110static int _PyPclose(FILE *file)
5111{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005112 int result;
5113 int exit_code;
5114 pid_t pipe_pid;
5115 PyObject *procObj, *pidObj, *intObj, *fileObj;
5116 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005117#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005118 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005119#endif
5120
Victor Stinnerd6f85422010-05-05 23:33:33 +00005121 /* Close the file handle first, to ensure it can't block the
5122 * child from exiting if it's the last handle.
5123 */
5124 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005125
5126#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005127 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005128#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005129 if (_PyPopenProcs)
5130 {
5131 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5132 (procObj = PyDict_GetItem(_PyPopenProcs,
5133 fileObj)) != NULL &&
5134 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
5135 (intObj = PyList_GetItem(procObj,1)) != NULL)
5136 {
5137 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
5138 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005139
Victor Stinnerd6f85422010-05-05 23:33:33 +00005140 if (file_count > 1)
5141 {
5142 /* Still other files referencing process */
5143 file_count--;
5144 PyList_SetItem(procObj,1,
5145 PyInt_FromLong((long) file_count));
5146 }
5147 else
5148 {
5149 /* Last file for this process */
5150 if (result != EOF &&
5151 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
5152 {
5153 /* extract exit status */
5154 if (WIFEXITED(exit_code))
5155 {
5156 result = WEXITSTATUS(exit_code);
5157 }
5158 else
5159 {
5160 errno = EPIPE;
5161 result = -1;
5162 }
5163 }
5164 else
5165 {
5166 /* Indicate failure - this will cause the file object
5167 * to raise an I/O error and translate the last
5168 * error code from errno. We do have a problem with
5169 * last errors that overlap the normal errno table,
5170 * but that's a consistent problem with the file object.
5171 */
5172 result = -1;
5173 }
5174 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005175
Victor Stinnerd6f85422010-05-05 23:33:33 +00005176 /* Remove this file pointer from dictionary */
5177 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005178
Victor Stinnerd6f85422010-05-05 23:33:33 +00005179 if (PyDict_Size(_PyPopenProcs) == 0)
5180 {
5181 Py_DECREF(_PyPopenProcs);
5182 _PyPopenProcs = NULL;
5183 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005184
Victor Stinnerd6f85422010-05-05 23:33:33 +00005185 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005186
Victor Stinnerd6f85422010-05-05 23:33:33 +00005187 Py_XDECREF(fileObj);
5188 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005189
5190#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005191 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005192#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005193 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005194}
5195
5196#endif /* PYCC_??? */
5197
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005198#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005199
5200/*
5201 * Portable 'popen' replacement for Win32.
5202 *
5203 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
5204 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00005205 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005206 */
5207
5208#include <malloc.h>
5209#include <io.h>
5210#include <fcntl.h>
5211
5212/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
5213#define POPEN_1 1
5214#define POPEN_2 2
5215#define POPEN_3 3
5216#define POPEN_4 4
5217
5218static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005219static int _PyPclose(FILE *file);
5220
5221/*
5222 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00005223 * for use when retrieving the process exit code. See _PyPclose() below
5224 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005225 */
5226static PyObject *_PyPopenProcs = NULL;
5227
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005228
5229/* popen that works from a GUI.
5230 *
5231 * The result of this function is a pipe (file) connected to the
5232 * processes stdin or stdout, depending on the requested mode.
5233 */
5234
5235static PyObject *
5236posix_popen(PyObject *self, PyObject *args)
5237{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005238 PyObject *f;
5239 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005240
Victor Stinnerd6f85422010-05-05 23:33:33 +00005241 char *cmdstring;
5242 char *mode = "r";
5243 int bufsize = -1;
5244 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5245 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005246
Victor Stinnerd6f85422010-05-05 23:33:33 +00005247 if (*mode == 'r')
5248 tm = _O_RDONLY;
5249 else if (*mode != 'w') {
5250 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5251 return NULL;
5252 } else
5253 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005254
Victor Stinnerd6f85422010-05-05 23:33:33 +00005255 if (bufsize != -1) {
5256 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5257 return NULL;
5258 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005259
Victor Stinnerd6f85422010-05-05 23:33:33 +00005260 if (*(mode+1) == 't')
5261 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5262 else if (*(mode+1) == 'b')
5263 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5264 else
5265 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005266
Victor Stinnerd6f85422010-05-05 23:33:33 +00005267 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005268}
5269
5270/* Variation on win32pipe.popen
5271 *
5272 * The result of this function is a pipe (file) connected to the
5273 * process's stdin, and a pipe connected to the process's stdout.
5274 */
5275
5276static PyObject *
5277win32_popen2(PyObject *self, PyObject *args)
5278{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005279 PyObject *f;
5280 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005281
Victor Stinnerd6f85422010-05-05 23:33:33 +00005282 char *cmdstring;
5283 char *mode = "t";
5284 int bufsize = -1;
5285 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5286 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005287
Victor Stinnerd6f85422010-05-05 23:33:33 +00005288 if (*mode == 't')
5289 tm = _O_TEXT;
5290 else if (*mode != 'b') {
5291 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5292 return NULL;
5293 } else
5294 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005295
Victor Stinnerd6f85422010-05-05 23:33:33 +00005296 if (bufsize != -1) {
5297 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5298 return NULL;
5299 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005300
Victor Stinnerd6f85422010-05-05 23:33:33 +00005301 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005302
Victor Stinnerd6f85422010-05-05 23:33:33 +00005303 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005304}
5305
5306/*
5307 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005308 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005309 * The result of this function is 3 pipes - the process's stdin,
5310 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005311 */
5312
5313static PyObject *
5314win32_popen3(PyObject *self, PyObject *args)
5315{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005316 PyObject *f;
5317 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005318
Victor Stinnerd6f85422010-05-05 23:33:33 +00005319 char *cmdstring;
5320 char *mode = "t";
5321 int bufsize = -1;
5322 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5323 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005324
Victor Stinnerd6f85422010-05-05 23:33:33 +00005325 if (*mode == 't')
5326 tm = _O_TEXT;
5327 else if (*mode != 'b') {
5328 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5329 return NULL;
5330 } else
5331 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005332
Victor Stinnerd6f85422010-05-05 23:33:33 +00005333 if (bufsize != -1) {
5334 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5335 return NULL;
5336 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005337
Victor Stinnerd6f85422010-05-05 23:33:33 +00005338 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005339
Victor Stinnerd6f85422010-05-05 23:33:33 +00005340 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341}
5342
5343/*
5344 * Variation on win32pipe.popen
5345 *
Tim Peters5aa91602002-01-30 05:46:57 +00005346 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005347 * and stdout+stderr combined as a single pipe.
5348 */
5349
5350static PyObject *
5351win32_popen4(PyObject *self, PyObject *args)
5352{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005353 PyObject *f;
5354 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005355
Victor Stinnerd6f85422010-05-05 23:33:33 +00005356 char *cmdstring;
5357 char *mode = "t";
5358 int bufsize = -1;
5359 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5360 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005361
Victor Stinnerd6f85422010-05-05 23:33:33 +00005362 if (*mode == 't')
5363 tm = _O_TEXT;
5364 else if (*mode != 'b') {
5365 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5366 return NULL;
5367 } else
5368 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005369
Victor Stinnerd6f85422010-05-05 23:33:33 +00005370 if (bufsize != -1) {
5371 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5372 return NULL;
5373 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005374
Victor Stinnerd6f85422010-05-05 23:33:33 +00005375 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005376
Victor Stinnerd6f85422010-05-05 23:33:33 +00005377 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005378}
5379
Mark Hammond08501372001-01-31 07:30:29 +00005380static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005381_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005382 HANDLE hStdin,
5383 HANDLE hStdout,
5384 HANDLE hStderr,
5385 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005386{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005387 PROCESS_INFORMATION piProcInfo;
5388 STARTUPINFO siStartInfo;
5389 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5390 char *s1,*s2, *s3 = " /c ";
5391 const char *szConsoleSpawn = "w9xpopen.exe";
5392 int i;
5393 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005394
Victor Stinnerd6f85422010-05-05 23:33:33 +00005395 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5396 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005397
Victor Stinnerd6f85422010-05-05 23:33:33 +00005398 s1 = (char *)alloca(i);
5399 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5400 /* x < i, so x fits into an integer */
5401 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005402
Victor Stinnerd6f85422010-05-05 23:33:33 +00005403 /* Explicitly check if we are using COMMAND.COM. If we are
5404 * then use the w9xpopen hack.
5405 */
5406 comshell = s1 + x;
5407 while (comshell >= s1 && *comshell != '\\')
5408 --comshell;
5409 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005410
Victor Stinnerd6f85422010-05-05 23:33:33 +00005411 if (GetVersion() < 0x80000000 &&
5412 _stricmp(comshell, "command.com") != 0) {
5413 /* NT/2000 and not using command.com. */
5414 x = i + strlen(s3) + strlen(cmdstring) + 1;
5415 s2 = (char *)alloca(x);
5416 ZeroMemory(s2, x);
5417 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5418 }
5419 else {
5420 /*
5421 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5422 * the workaround listed in KB: Q150956
5423 */
5424 char modulepath[_MAX_PATH];
5425 struct stat statinfo;
5426 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5427 for (x = i = 0; modulepath[i]; i++)
5428 if (modulepath[i] == SEP)
5429 x = i+1;
5430 modulepath[x] = '\0';
5431 /* Create the full-name to w9xpopen, so we can test it exists */
5432 strncat(modulepath,
5433 szConsoleSpawn,
5434 (sizeof(modulepath)/sizeof(modulepath[0]))
5435 -strlen(modulepath));
5436 if (stat(modulepath, &statinfo) != 0) {
5437 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5438 /* Eeek - file-not-found - possibly an embedding
5439 situation - see if we can locate it in sys.prefix
5440 */
5441 strncpy(modulepath,
5442 Py_GetExecPrefix(),
5443 mplen);
5444 modulepath[mplen-1] = '\0';
5445 if (modulepath[strlen(modulepath)-1] != '\\')
5446 strcat(modulepath, "\\");
5447 strncat(modulepath,
5448 szConsoleSpawn,
5449 mplen-strlen(modulepath));
5450 /* No where else to look - raise an easily identifiable
5451 error, rather than leaving Windows to report
5452 "file not found" - as the user is probably blissfully
5453 unaware this shim EXE is used, and it will confuse them.
5454 (well, it confused me for a while ;-)
5455 */
5456 if (stat(modulepath, &statinfo) != 0) {
5457 PyErr_Format(PyExc_RuntimeError,
5458 "Can not locate '%s' which is needed "
5459 "for popen to work with your shell "
5460 "or platform.",
5461 szConsoleSpawn);
5462 return FALSE;
5463 }
5464 }
5465 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5466 strlen(modulepath) +
5467 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005468
Victor Stinnerd6f85422010-05-05 23:33:33 +00005469 s2 = (char *)alloca(x);
5470 ZeroMemory(s2, x);
5471 /* To maintain correct argument passing semantics,
5472 we pass the command-line as it stands, and allow
5473 quoting to be applied. w9xpopen.exe will then
5474 use its argv vector, and re-quote the necessary
5475 args for the ultimate child process.
5476 */
5477 PyOS_snprintf(
5478 s2, x,
5479 "\"%s\" %s%s%s",
5480 modulepath,
5481 s1,
5482 s3,
5483 cmdstring);
5484 /* Not passing CREATE_NEW_CONSOLE has been known to
5485 cause random failures on win9x. Specifically a
5486 dialog:
5487 "Your program accessed mem currently in use at xxx"
5488 and a hopeful warning about the stability of your
5489 system.
5490 Cost is Ctrl+C won't kill children, but anyone
5491 who cares can have a go!
5492 */
5493 dwProcessFlags |= CREATE_NEW_CONSOLE;
5494 }
5495 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005496
Victor Stinnerd6f85422010-05-05 23:33:33 +00005497 /* Could be an else here to try cmd.exe / command.com in the path
5498 Now we'll just error out.. */
5499 else {
5500 PyErr_SetString(PyExc_RuntimeError,
5501 "Cannot locate a COMSPEC environment variable to "
5502 "use as the shell");
5503 return FALSE;
5504 }
Tim Peters5aa91602002-01-30 05:46:57 +00005505
Victor Stinnerd6f85422010-05-05 23:33:33 +00005506 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5507 siStartInfo.cb = sizeof(STARTUPINFO);
5508 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5509 siStartInfo.hStdInput = hStdin;
5510 siStartInfo.hStdOutput = hStdout;
5511 siStartInfo.hStdError = hStderr;
5512 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005513
Victor Stinnerd6f85422010-05-05 23:33:33 +00005514 if (CreateProcess(NULL,
5515 s2,
5516 NULL,
5517 NULL,
5518 TRUE,
5519 dwProcessFlags,
5520 NULL,
5521 NULL,
5522 &siStartInfo,
5523 &piProcInfo) ) {
5524 /* Close the handles now so anyone waiting is woken. */
5525 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005526
Victor Stinnerd6f85422010-05-05 23:33:33 +00005527 /* Return process handle */
5528 *hProcess = piProcInfo.hProcess;
5529 return TRUE;
5530 }
5531 win32_error("CreateProcess", s2);
5532 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005533}
5534
5535/* The following code is based off of KB: Q190351 */
5536
5537static PyObject *
5538_PyPopen(char *cmdstring, int mode, int n)
5539{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005540 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5541 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5542 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005543
Victor Stinnerd6f85422010-05-05 23:33:33 +00005544 SECURITY_ATTRIBUTES saAttr;
5545 BOOL fSuccess;
5546 int fd1, fd2, fd3;
5547 FILE *f1, *f2, *f3;
5548 long file_count;
5549 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005550
Victor Stinnerd6f85422010-05-05 23:33:33 +00005551 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5552 saAttr.bInheritHandle = TRUE;
5553 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005554
Victor Stinnerd6f85422010-05-05 23:33:33 +00005555 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5556 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005557
Victor Stinnerd6f85422010-05-05 23:33:33 +00005558 /* Create new output read handle and the input write handle. Set
5559 * the inheritance properties to FALSE. Otherwise, the child inherits
5560 * these handles; resulting in non-closeable handles to the pipes
5561 * being created. */
5562 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5563 GetCurrentProcess(), &hChildStdinWrDup, 0,
5564 FALSE,
5565 DUPLICATE_SAME_ACCESS);
5566 if (!fSuccess)
5567 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005568
Victor Stinnerd6f85422010-05-05 23:33:33 +00005569 /* Close the inheritable version of ChildStdin
5570 that we're using. */
5571 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005572
Victor Stinnerd6f85422010-05-05 23:33:33 +00005573 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5574 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005575
Victor Stinnerd6f85422010-05-05 23:33:33 +00005576 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5577 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5578 FALSE, DUPLICATE_SAME_ACCESS);
5579 if (!fSuccess)
5580 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005581
Victor Stinnerd6f85422010-05-05 23:33:33 +00005582 /* Close the inheritable version of ChildStdout
5583 that we're using. */
5584 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005585
Victor Stinnerd6f85422010-05-05 23:33:33 +00005586 if (n != POPEN_4) {
5587 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5588 return win32_error("CreatePipe", NULL);
5589 fSuccess = DuplicateHandle(GetCurrentProcess(),
5590 hChildStderrRd,
5591 GetCurrentProcess(),
5592 &hChildStderrRdDup, 0,
5593 FALSE, DUPLICATE_SAME_ACCESS);
5594 if (!fSuccess)
5595 return win32_error("DuplicateHandle", NULL);
5596 /* Close the inheritable version of ChildStdErr that we're using. */
5597 CloseHandle(hChildStderrRd);
5598 }
Tim Peters5aa91602002-01-30 05:46:57 +00005599
Victor Stinnerd6f85422010-05-05 23:33:33 +00005600 switch (n) {
5601 case POPEN_1:
5602 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5603 case _O_WRONLY | _O_TEXT:
5604 /* Case for writing to child Stdin in text mode. */
5605 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5606 f1 = _fdopen(fd1, "w");
5607 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5608 PyFile_SetBufSize(f, 0);
5609 /* We don't care about these pipes anymore, so close them. */
5610 CloseHandle(hChildStdoutRdDup);
5611 CloseHandle(hChildStderrRdDup);
5612 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005613
Victor Stinnerd6f85422010-05-05 23:33:33 +00005614 case _O_RDONLY | _O_TEXT:
5615 /* Case for reading from child Stdout in text mode. */
5616 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5617 f1 = _fdopen(fd1, "r");
5618 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5619 PyFile_SetBufSize(f, 0);
5620 /* We don't care about these pipes anymore, so close them. */
5621 CloseHandle(hChildStdinWrDup);
5622 CloseHandle(hChildStderrRdDup);
5623 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005624
Victor Stinnerd6f85422010-05-05 23:33:33 +00005625 case _O_RDONLY | _O_BINARY:
5626 /* Case for readinig from child Stdout in binary mode. */
5627 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5628 f1 = _fdopen(fd1, "rb");
5629 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5630 PyFile_SetBufSize(f, 0);
5631 /* We don't care about these pipes anymore, so close them. */
5632 CloseHandle(hChildStdinWrDup);
5633 CloseHandle(hChildStderrRdDup);
5634 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005635
Victor Stinnerd6f85422010-05-05 23:33:33 +00005636 case _O_WRONLY | _O_BINARY:
5637 /* Case for writing to child Stdin in binary mode. */
5638 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5639 f1 = _fdopen(fd1, "wb");
5640 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5641 PyFile_SetBufSize(f, 0);
5642 /* We don't care about these pipes anymore, so close them. */
5643 CloseHandle(hChildStdoutRdDup);
5644 CloseHandle(hChildStderrRdDup);
5645 break;
5646 }
5647 file_count = 1;
5648 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005649
Victor Stinnerd6f85422010-05-05 23:33:33 +00005650 case POPEN_2:
5651 case POPEN_4:
5652 {
5653 char *m1, *m2;
5654 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005655
Victor Stinnerd6f85422010-05-05 23:33:33 +00005656 if (mode & _O_TEXT) {
5657 m1 = "r";
5658 m2 = "w";
5659 } else {
5660 m1 = "rb";
5661 m2 = "wb";
5662 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005663
Victor Stinnerd6f85422010-05-05 23:33:33 +00005664 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5665 f1 = _fdopen(fd1, m2);
5666 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5667 f2 = _fdopen(fd2, m1);
5668 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5669 PyFile_SetBufSize(p1, 0);
5670 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5671 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005672
Victor Stinnerd6f85422010-05-05 23:33:33 +00005673 if (n != 4)
5674 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005675
Victor Stinnerd6f85422010-05-05 23:33:33 +00005676 f = PyTuple_Pack(2,p1,p2);
5677 Py_XDECREF(p1);
5678 Py_XDECREF(p2);
5679 file_count = 2;
5680 break;
5681 }
Tim Peters5aa91602002-01-30 05:46:57 +00005682
Victor Stinnerd6f85422010-05-05 23:33:33 +00005683 case POPEN_3:
5684 {
5685 char *m1, *m2;
5686 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005687
Victor Stinnerd6f85422010-05-05 23:33:33 +00005688 if (mode & _O_TEXT) {
5689 m1 = "r";
5690 m2 = "w";
5691 } else {
5692 m1 = "rb";
5693 m2 = "wb";
5694 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005695
Victor Stinnerd6f85422010-05-05 23:33:33 +00005696 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5697 f1 = _fdopen(fd1, m2);
5698 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5699 f2 = _fdopen(fd2, m1);
5700 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5701 f3 = _fdopen(fd3, m1);
5702 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5703 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5704 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5705 PyFile_SetBufSize(p1, 0);
5706 PyFile_SetBufSize(p2, 0);
5707 PyFile_SetBufSize(p3, 0);
5708 f = PyTuple_Pack(3,p1,p2,p3);
5709 Py_XDECREF(p1);
5710 Py_XDECREF(p2);
5711 Py_XDECREF(p3);
5712 file_count = 3;
5713 break;
5714 }
5715 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005716
Victor Stinnerd6f85422010-05-05 23:33:33 +00005717 if (n == POPEN_4) {
5718 if (!_PyPopenCreateProcess(cmdstring,
5719 hChildStdinRd,
5720 hChildStdoutWr,
5721 hChildStdoutWr,
5722 &hProcess))
5723 return NULL;
5724 }
5725 else {
5726 if (!_PyPopenCreateProcess(cmdstring,
5727 hChildStdinRd,
5728 hChildStdoutWr,
5729 hChildStderrWr,
5730 &hProcess))
5731 return NULL;
5732 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005733
Victor Stinnerd6f85422010-05-05 23:33:33 +00005734 /*
5735 * Insert the files we've created into the process dictionary
5736 * all referencing the list with the process handle and the
5737 * initial number of files (see description below in _PyPclose).
5738 * Since if _PyPclose later tried to wait on a process when all
5739 * handles weren't closed, it could create a deadlock with the
5740 * child, we spend some energy here to try to ensure that we
5741 * either insert all file handles into the dictionary or none
5742 * at all. It's a little clumsy with the various popen modes
5743 * and variable number of files involved.
5744 */
5745 if (!_PyPopenProcs) {
5746 _PyPopenProcs = PyDict_New();
5747 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005748
Victor Stinnerd6f85422010-05-05 23:33:33 +00005749 if (_PyPopenProcs) {
5750 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5751 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005752
Victor Stinnerd6f85422010-05-05 23:33:33 +00005753 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5754 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005755
Victor Stinnerd6f85422010-05-05 23:33:33 +00005756 procObj = PyList_New(2);
5757 hProcessObj = PyLong_FromVoidPtr(hProcess);
5758 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005759
Victor Stinnerd6f85422010-05-05 23:33:33 +00005760 if (procObj && hProcessObj && intObj) {
5761 PyList_SetItem(procObj,0,hProcessObj);
5762 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005763
Victor Stinnerd6f85422010-05-05 23:33:33 +00005764 fileObj[0] = PyLong_FromVoidPtr(f1);
5765 if (fileObj[0]) {
5766 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5767 fileObj[0],
5768 procObj);
5769 }
5770 if (file_count >= 2) {
5771 fileObj[1] = PyLong_FromVoidPtr(f2);
5772 if (fileObj[1]) {
5773 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5774 fileObj[1],
5775 procObj);
5776 }
5777 }
5778 if (file_count >= 3) {
5779 fileObj[2] = PyLong_FromVoidPtr(f3);
5780 if (fileObj[2]) {
5781 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5782 fileObj[2],
5783 procObj);
5784 }
5785 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005786
Victor Stinnerd6f85422010-05-05 23:33:33 +00005787 if (ins_rc[0] < 0 || !fileObj[0] ||
5788 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5789 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5790 /* Something failed - remove any dictionary
5791 * entries that did make it.
5792 */
5793 if (!ins_rc[0] && fileObj[0]) {
5794 PyDict_DelItem(_PyPopenProcs,
5795 fileObj[0]);
5796 }
5797 if (!ins_rc[1] && fileObj[1]) {
5798 PyDict_DelItem(_PyPopenProcs,
5799 fileObj[1]);
5800 }
5801 if (!ins_rc[2] && fileObj[2]) {
5802 PyDict_DelItem(_PyPopenProcs,
5803 fileObj[2]);
5804 }
5805 }
5806 }
Tim Peters5aa91602002-01-30 05:46:57 +00005807
Victor Stinnerd6f85422010-05-05 23:33:33 +00005808 /*
5809 * Clean up our localized references for the dictionary keys
5810 * and value since PyDict_SetItem will Py_INCREF any copies
5811 * that got placed in the dictionary.
5812 */
5813 Py_XDECREF(procObj);
5814 Py_XDECREF(fileObj[0]);
5815 Py_XDECREF(fileObj[1]);
5816 Py_XDECREF(fileObj[2]);
5817 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005818
Victor Stinnerd6f85422010-05-05 23:33:33 +00005819 /* Child is launched. Close the parents copy of those pipe
5820 * handles that only the child should have open. You need to
5821 * make sure that no handles to the write end of the output pipe
5822 * are maintained in this process or else the pipe will not close
5823 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005824
Victor Stinnerd6f85422010-05-05 23:33:33 +00005825 if (!CloseHandle(hChildStdinRd))
5826 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005827
Victor Stinnerd6f85422010-05-05 23:33:33 +00005828 if (!CloseHandle(hChildStdoutWr))
5829 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005830
Victor Stinnerd6f85422010-05-05 23:33:33 +00005831 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5832 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005833
Victor Stinnerd6f85422010-05-05 23:33:33 +00005834 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005835}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005836
5837/*
5838 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5839 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005840 *
5841 * This function uses the _PyPopenProcs dictionary in order to map the
5842 * input file pointer to information about the process that was
5843 * originally created by the popen* call that created the file pointer.
5844 * The dictionary uses the file pointer as a key (with one entry
5845 * inserted for each file returned by the original popen* call) and a
5846 * single list object as the value for all files from a single call.
5847 * The list object contains the Win32 process handle at [0], and a file
5848 * count at [1], which is initialized to the total number of file
5849 * handles using that list.
5850 *
5851 * This function closes whichever handle it is passed, and decrements
5852 * the file count in the dictionary for the process handle pointed to
5853 * by this file. On the last close (when the file count reaches zero),
5854 * this function will wait for the child process and then return its
5855 * exit code as the result of the close() operation. This permits the
5856 * files to be closed in any order - it is always the close() of the
5857 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005858 *
5859 * NOTE: This function is currently called with the GIL released.
5860 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005861 */
Tim Peters736aa322000-09-01 06:51:24 +00005862
Fredrik Lundh56055a42000-07-23 19:47:12 +00005863static int _PyPclose(FILE *file)
5864{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005865 int result;
5866 DWORD exit_code;
5867 HANDLE hProcess;
5868 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5869 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005870#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005871 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005872#endif
5873
Victor Stinnerd6f85422010-05-05 23:33:33 +00005874 /* Close the file handle first, to ensure it can't block the
5875 * child from exiting if it's the last handle.
5876 */
5877 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005878#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005879 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005880#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005881 if (_PyPopenProcs) {
5882 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5883 (procObj = PyDict_GetItem(_PyPopenProcs,
5884 fileObj)) != NULL &&
5885 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5886 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005887
Victor Stinnerd6f85422010-05-05 23:33:33 +00005888 hProcess = PyLong_AsVoidPtr(hProcessObj);
5889 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005890
Victor Stinnerd6f85422010-05-05 23:33:33 +00005891 if (file_count > 1) {
5892 /* Still other files referencing process */
5893 file_count--;
5894 PyList_SetItem(procObj,1,
5895 PyInt_FromLong(file_count));
5896 } else {
5897 /* Last file for this process */
5898 if (result != EOF &&
5899 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5900 GetExitCodeProcess(hProcess, &exit_code)) {
5901 /* Possible truncation here in 16-bit environments, but
5902 * real exit codes are just the lower byte in any event.
5903 */
5904 result = exit_code;
5905 } else {
5906 /* Indicate failure - this will cause the file object
5907 * to raise an I/O error and translate the last Win32
5908 * error code from errno. We do have a problem with
5909 * last errors that overlap the normal errno table,
5910 * but that's a consistent problem with the file object.
5911 */
5912 if (result != EOF) {
5913 /* If the error wasn't from the fclose(), then
5914 * set errno for the file object error handling.
5915 */
5916 errno = GetLastError();
5917 }
5918 result = -1;
5919 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005920
Victor Stinnerd6f85422010-05-05 23:33:33 +00005921 /* Free up the native handle at this point */
5922 CloseHandle(hProcess);
5923 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005924
Victor Stinnerd6f85422010-05-05 23:33:33 +00005925 /* Remove this file pointer from dictionary */
5926 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005927
Victor Stinnerd6f85422010-05-05 23:33:33 +00005928 if (PyDict_Size(_PyPopenProcs) == 0) {
5929 Py_DECREF(_PyPopenProcs);
5930 _PyPopenProcs = NULL;
5931 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005932
Victor Stinnerd6f85422010-05-05 23:33:33 +00005933 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005934
Victor Stinnerd6f85422010-05-05 23:33:33 +00005935 Py_XDECREF(fileObj);
5936 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005937
Tim Peters736aa322000-09-01 06:51:24 +00005938#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005939 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005940#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005941 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005942}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005943
5944#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005947{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005948 char *name;
5949 char *mode = "r";
5950 int bufsize = -1;
5951 FILE *fp;
5952 PyObject *f;
5953 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5954 return NULL;
5955 /* Strip mode of binary or text modifiers */
5956 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5957 mode = "r";
5958 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5959 mode = "w";
5960 Py_BEGIN_ALLOW_THREADS
5961 fp = popen(name, mode);
5962 Py_END_ALLOW_THREADS
5963 if (fp == NULL)
5964 return posix_error();
5965 f = PyFile_FromFile(fp, name, mode, pclose);
5966 if (f != NULL)
5967 PyFile_SetBufSize(f, bufsize);
5968 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005969}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005970
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005971#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005972#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005974
Guido van Rossumb6775db1994-08-01 11:34:53 +00005975#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005977"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005978Set the current process's user id.");
5979
Barry Warsaw53699e91996-12-10 23:23:01 +00005980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005981posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005982{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005983 uid_t uid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02005984 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00005985 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00005986 if (setuid(uid) < 0)
5987 return posix_error();
5988 Py_INCREF(Py_None);
5989 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005990}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005991#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005993
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005994#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005996"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005997Set the current process's effective user id.");
5998
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005999static PyObject *
6000posix_seteuid (PyObject *self, PyObject *args)
6001{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006002 uid_t euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006003 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006004 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006005 if (seteuid(euid) < 0) {
6006 return posix_error();
6007 } else {
6008 Py_INCREF(Py_None);
6009 return Py_None;
6010 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006011}
6012#endif /* HAVE_SETEUID */
6013
6014#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006015PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006016"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006017Set the current process's effective group id.");
6018
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006019static PyObject *
6020posix_setegid (PyObject *self, PyObject *args)
6021{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006022 gid_t egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006023 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006024 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006025 if (setegid(egid) < 0) {
6026 return posix_error();
6027 } else {
6028 Py_INCREF(Py_None);
6029 return Py_None;
6030 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006031}
6032#endif /* HAVE_SETEGID */
6033
6034#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006036"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006037Set the current process's real and effective user ids.");
6038
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006039static PyObject *
6040posix_setreuid (PyObject *self, PyObject *args)
6041{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006042 uid_t ruid, euid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006043 if (!PyArg_ParseTuple(args, "O&O&:setreuid",
6044 _Py_Uid_Converter, &ruid,
6045 _Py_Uid_Converter, &euid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006046 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006047 if (setreuid(ruid, euid) < 0) {
6048 return posix_error();
6049 } else {
6050 Py_INCREF(Py_None);
6051 return Py_None;
6052 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006053}
6054#endif /* HAVE_SETREUID */
6055
6056#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006057PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00006058"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006059Set the current process's real and effective group ids.");
6060
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006061static PyObject *
6062posix_setregid (PyObject *self, PyObject *args)
6063{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006064 gid_t rgid, egid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006065 if (!PyArg_ParseTuple(args, "O&O&:setregid",
6066 _Py_Gid_Converter, &rgid,
6067 _Py_Gid_Converter, &egid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006068 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006069 if (setregid(rgid, egid) < 0) {
6070 return posix_error();
6071 } else {
6072 Py_INCREF(Py_None);
6073 return Py_None;
6074 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006075}
6076#endif /* HAVE_SETREGID */
6077
Guido van Rossumb6775db1994-08-01 11:34:53 +00006078#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Barry Warsaw53699e91996-12-10 23:23:01 +00006083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006085{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006086 gid_t gid;
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006087 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00006088 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006089 if (setgid(gid) < 0)
6090 return posix_error();
6091 Py_INCREF(Py_None);
6092 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006093}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006094#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006095
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006096#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006100
6101static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00006102posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006103{
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006104 Py_ssize_t i, len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006105 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006106
Victor Stinnerd6f85422010-05-05 23:33:33 +00006107 if (!PySequence_Check(groups)) {
6108 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6109 return NULL;
6110 }
6111 len = PySequence_Size(groups);
Serhiy Storchaka64aa4df2017-04-19 22:34:58 +03006112 if (len < 0) {
6113 return NULL;
6114 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006115 if (len > MAX_GROUPS) {
6116 PyErr_SetString(PyExc_ValueError, "too many groups");
6117 return NULL;
6118 }
6119 for(i = 0; i < len; i++) {
6120 PyObject *elem;
6121 elem = PySequence_GetItem(groups, i);
6122 if (!elem)
6123 return NULL;
Serhiy Storchaka48c8bf22018-07-31 09:09:36 +03006124 if (!_PyAnyInt_Check(elem)) {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006125 PyErr_SetString(PyExc_TypeError,
6126 "groups must be integers");
6127 Py_DECREF(elem);
6128 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006129 } else {
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02006130 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006131 Py_DECREF(elem);
6132 return NULL;
6133 }
6134 }
6135 Py_DECREF(elem);
6136 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006137
Victor Stinnerd6f85422010-05-05 23:33:33 +00006138 if (setgroups(len, grouplist) < 0)
6139 return posix_error();
6140 Py_INCREF(Py_None);
6141 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006142}
6143#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006144
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006145#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00006146static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00006147wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00006148{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006149 PyObject *result;
6150 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00006151
Victor Stinnerd6f85422010-05-05 23:33:33 +00006152 if (pid == -1)
6153 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00006154
Victor Stinnerd6f85422010-05-05 23:33:33 +00006155 if (struct_rusage == NULL) {
6156 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6157 if (m == NULL)
6158 return NULL;
6159 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
6160 Py_DECREF(m);
6161 if (struct_rusage == NULL)
6162 return NULL;
6163 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006164
Victor Stinnerd6f85422010-05-05 23:33:33 +00006165 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6166 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6167 if (!result)
6168 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006169
6170#ifndef doubletime
6171#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6172#endif
6173
Victor Stinnerd6f85422010-05-05 23:33:33 +00006174 PyStructSequence_SET_ITEM(result, 0,
6175 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6176 PyStructSequence_SET_ITEM(result, 1,
6177 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006178#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006179 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6180 SET_INT(result, 2, ru->ru_maxrss);
6181 SET_INT(result, 3, ru->ru_ixrss);
6182 SET_INT(result, 4, ru->ru_idrss);
6183 SET_INT(result, 5, ru->ru_isrss);
6184 SET_INT(result, 6, ru->ru_minflt);
6185 SET_INT(result, 7, ru->ru_majflt);
6186 SET_INT(result, 8, ru->ru_nswap);
6187 SET_INT(result, 9, ru->ru_inblock);
6188 SET_INT(result, 10, ru->ru_oublock);
6189 SET_INT(result, 11, ru->ru_msgsnd);
6190 SET_INT(result, 12, ru->ru_msgrcv);
6191 SET_INT(result, 13, ru->ru_nsignals);
6192 SET_INT(result, 14, ru->ru_nvcsw);
6193 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006194#undef SET_INT
6195
Victor Stinnerd6f85422010-05-05 23:33:33 +00006196 if (PyErr_Occurred()) {
6197 Py_DECREF(result);
6198 return NULL;
6199 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006200
Victor Stinnerd6f85422010-05-05 23:33:33 +00006201 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006202}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006203#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006204
6205#ifdef HAVE_WAIT3
6206PyDoc_STRVAR(posix_wait3__doc__,
6207"wait3(options) -> (pid, status, rusage)\n\n\
6208Wait for completion of a child process.");
6209
6210static PyObject *
6211posix_wait3(PyObject *self, PyObject *args)
6212{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006213 pid_t pid;
6214 int options;
6215 struct rusage ru;
6216 WAIT_TYPE status;
6217 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006218
Victor Stinnerd6f85422010-05-05 23:33:33 +00006219 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6220 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006221
Victor Stinnerd6f85422010-05-05 23:33:33 +00006222 Py_BEGIN_ALLOW_THREADS
6223 pid = wait3(&status, options, &ru);
6224 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006225
Victor Stinnerd6f85422010-05-05 23:33:33 +00006226 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006227}
6228#endif /* HAVE_WAIT3 */
6229
6230#ifdef HAVE_WAIT4
6231PyDoc_STRVAR(posix_wait4__doc__,
6232"wait4(pid, options) -> (pid, status, rusage)\n\n\
6233Wait for completion of a given child process.");
6234
6235static PyObject *
6236posix_wait4(PyObject *self, PyObject *args)
6237{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006238 pid_t pid;
6239 int options;
6240 struct rusage ru;
6241 WAIT_TYPE status;
6242 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006243
Victor Stinnerd6f85422010-05-05 23:33:33 +00006244 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6245 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006246
Victor Stinnerd6f85422010-05-05 23:33:33 +00006247 Py_BEGIN_ALLOW_THREADS
6248 pid = wait4(pid, &status, options, &ru);
6249 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006250
Victor Stinnerd6f85422010-05-05 23:33:33 +00006251 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006252}
6253#endif /* HAVE_WAIT4 */
6254
Guido van Rossumb6775db1994-08-01 11:34:53 +00006255#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006256PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006257"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006258Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006259
Barry Warsaw53699e91996-12-10 23:23:01 +00006260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006261posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006262{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006263 pid_t pid;
6264 int options;
6265 WAIT_TYPE status;
6266 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006267
Victor Stinnerd6f85422010-05-05 23:33:33 +00006268 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6269 return NULL;
6270 Py_BEGIN_ALLOW_THREADS
6271 pid = waitpid(pid, &status, options);
6272 Py_END_ALLOW_THREADS
6273 if (pid == -1)
6274 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006275
Victor Stinnerd6f85422010-05-05 23:33:33 +00006276 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006277}
6278
Tim Petersab034fa2002-02-01 11:27:43 +00006279#elif defined(HAVE_CWAIT)
6280
6281/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006285
6286static PyObject *
6287posix_waitpid(PyObject *self, PyObject *args)
6288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006289 Py_intptr_t pid;
6290 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006291
Victor Stinnerd6f85422010-05-05 23:33:33 +00006292 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6293 return NULL;
6294 Py_BEGIN_ALLOW_THREADS
6295 pid = _cwait(&status, pid, options);
6296 Py_END_ALLOW_THREADS
6297 if (pid == -1)
6298 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006299
Victor Stinnerd6f85422010-05-05 23:33:33 +00006300 /* shift the status left a byte so this is more like the POSIX waitpid */
6301 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006302}
6303#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006304
Guido van Rossumad0ee831995-03-01 10:34:45 +00006305#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006306PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006307"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006309
Barry Warsaw53699e91996-12-10 23:23:01 +00006310static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006311posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006312{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006313 pid_t pid;
6314 WAIT_TYPE status;
6315 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006316
Victor Stinnerd6f85422010-05-05 23:33:33 +00006317 Py_BEGIN_ALLOW_THREADS
6318 pid = wait(&status);
6319 Py_END_ALLOW_THREADS
6320 if (pid == -1)
6321 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006322
Victor Stinnerd6f85422010-05-05 23:33:33 +00006323 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006324}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006325#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006328PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006329"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006330Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006331
Barry Warsaw53699e91996-12-10 23:23:01 +00006332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006333posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006334{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006335#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006336 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006337#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006338#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006339 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006340#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006341 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006342#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006343#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006344}
6345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006346
Guido van Rossumb6775db1994-08-01 11:34:53 +00006347#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006351
Barry Warsaw53699e91996-12-10 23:23:01 +00006352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006353posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006354{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006355 PyObject* v;
6356 char buf[MAXPATHLEN];
6357 char *path;
6358 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006359#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006360 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006361#endif
6362
Victor Stinnerd6f85422010-05-05 23:33:33 +00006363 if (!PyArg_ParseTuple(args, "et:readlink",
6364 Py_FileSystemDefaultEncoding, &path))
6365 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006366#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006367 v = PySequence_GetItem(args, 0);
6368 if (v == NULL) {
6369 PyMem_Free(path);
6370 return NULL;
6371 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006372
Victor Stinnerd6f85422010-05-05 23:33:33 +00006373 if (PyUnicode_Check(v)) {
6374 arg_is_unicode = 1;
6375 }
6376 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006377#endif
6378
Victor Stinnerd6f85422010-05-05 23:33:33 +00006379 Py_BEGIN_ALLOW_THREADS
6380 n = readlink(path, buf, (int) sizeof buf);
6381 Py_END_ALLOW_THREADS
6382 if (n < 0)
6383 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006384
Victor Stinnerd6f85422010-05-05 23:33:33 +00006385 PyMem_Free(path);
6386 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006387#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006388 if (arg_is_unicode) {
6389 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006390
Victor Stinnerd6f85422010-05-05 23:33:33 +00006391 w = PyUnicode_FromEncodedObject(v,
6392 Py_FileSystemDefaultEncoding,
6393 "strict");
6394 if (w != NULL) {
6395 Py_DECREF(v);
6396 v = w;
6397 }
6398 else {
6399 /* fall back to the original byte string, as
6400 discussed in patch #683592 */
6401 PyErr_Clear();
6402 }
6403 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006404#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006405 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006406}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006407#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006409
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006413Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006414
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006417{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006418 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006419}
6420#endif /* HAVE_SYMLINK */
6421
6422
6423#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006424#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6425static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006426system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006427{
6428 ULONG value = 0;
6429
6430 Py_BEGIN_ALLOW_THREADS
6431 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6432 Py_END_ALLOW_THREADS
6433
6434 return value;
6435}
6436
6437static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006438posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006439{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006440 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006441 return Py_BuildValue("ddddd",
6442 (double)0 /* t.tms_utime / HZ */,
6443 (double)0 /* t.tms_stime / HZ */,
6444 (double)0 /* t.tms_cutime / HZ */,
6445 (double)0 /* t.tms_cstime / HZ */,
6446 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006447}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006448#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006449#define NEED_TICKS_PER_SECOND
6450static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006451static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006452posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006453{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006454 struct tms t;
6455 clock_t c;
6456 errno = 0;
6457 c = times(&t);
6458 if (c == (clock_t) -1)
6459 return posix_error();
6460 return Py_BuildValue("ddddd",
6461 (double)t.tms_utime / ticks_per_second,
6462 (double)t.tms_stime / ticks_per_second,
6463 (double)t.tms_cutime / ticks_per_second,
6464 (double)t.tms_cstime / ticks_per_second,
6465 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006466}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006467#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006468#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006469
6470
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006471#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006472#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006473static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006474posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006475{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006476 FILETIME create, exit, kernel, user;
6477 HANDLE hProc;
6478 hProc = GetCurrentProcess();
6479 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6480 /* The fields of a FILETIME structure are the hi and lo part
6481 of a 64-bit value expressed in 100 nanosecond units.
6482 1e7 is one second in such units; 1e-7 the inverse.
6483 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6484 */
6485 return Py_BuildValue(
6486 "ddddd",
6487 (double)(user.dwHighDateTime*429.4967296 +
6488 user.dwLowDateTime*1e-7),
6489 (double)(kernel.dwHighDateTime*429.4967296 +
6490 kernel.dwLowDateTime*1e-7),
6491 (double)0,
6492 (double)0,
6493 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006494}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006495#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006496
6497#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006498PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006499"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006500Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006501#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006503
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006504#ifdef HAVE_GETSID
6505PyDoc_STRVAR(posix_getsid__doc__,
6506"getsid(pid) -> sid\n\n\
6507Call the system call getsid().");
6508
6509static PyObject *
6510posix_getsid(PyObject *self, PyObject *args)
6511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006512 pid_t pid;
6513 int sid;
6514 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6515 return NULL;
6516 sid = getsid(pid);
6517 if (sid < 0)
6518 return posix_error();
6519 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006520}
6521#endif /* HAVE_GETSID */
6522
6523
Guido van Rossumb6775db1994-08-01 11:34:53 +00006524#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006526"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006527Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Barry Warsaw53699e91996-12-10 23:23:01 +00006529static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006530posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006531{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006532 if (setsid() < 0)
6533 return posix_error();
6534 Py_INCREF(Py_None);
6535 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006536}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006537#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006538
Guido van Rossumb6775db1994-08-01 11:34:53 +00006539#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006540PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006541"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006542Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006543
Barry Warsaw53699e91996-12-10 23:23:01 +00006544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006545posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006546{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006547 pid_t pid;
6548 int pgrp;
6549 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6550 return NULL;
6551 if (setpgid(pid, pgrp) < 0)
6552 return posix_error();
6553 Py_INCREF(Py_None);
6554 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006555}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006556#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006557
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006558
Guido van Rossumb6775db1994-08-01 11:34:53 +00006559#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006561"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006563
Barry Warsaw53699e91996-12-10 23:23:01 +00006564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006565posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006566{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006567 int fd;
6568 pid_t pgid;
6569 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6570 return NULL;
6571 pgid = tcgetpgrp(fd);
6572 if (pgid < 0)
6573 return posix_error();
6574 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006575}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006576#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006578
Guido van Rossumb6775db1994-08-01 11:34:53 +00006579#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006581"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006583
Barry Warsaw53699e91996-12-10 23:23:01 +00006584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006585posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006586{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006587 int fd;
6588 pid_t pgid;
6589 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6590 return NULL;
6591 if (tcsetpgrp(fd, pgid) < 0)
6592 return posix_error();
6593 Py_INCREF(Py_None);
6594 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006595}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006596#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006597
Guido van Rossum687dd131993-05-17 08:34:16 +00006598/* Functions acting on file descriptors */
6599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006601"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006602Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006603
Barry Warsaw53699e91996-12-10 23:23:01 +00006604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006605posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006606{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006607 char *file = NULL;
6608 int flag;
6609 int mode = 0777;
6610 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006611
6612#ifdef MS_WINDOWS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006613 Py_UNICODE *wpath;
6614 if (PyArg_ParseTuple(args, "ui|i:mkdir", &wpath, &flag, &mode)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00006615 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03006616 fd = _wopen(wpath, flag, mode);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006617 Py_END_ALLOW_THREADS
6618 if (fd < 0)
6619 return posix_error();
6620 return PyInt_FromLong((long)fd);
6621 }
6622 /* Drop the argument parsing error as narrow strings
6623 are also valid. */
6624 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006625#endif
6626
Victor Stinnerd6f85422010-05-05 23:33:33 +00006627 if (!PyArg_ParseTuple(args, "eti|i",
6628 Py_FileSystemDefaultEncoding, &file,
6629 &flag, &mode))
6630 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006631
Victor Stinnerd6f85422010-05-05 23:33:33 +00006632 Py_BEGIN_ALLOW_THREADS
6633 fd = open(file, flag, mode);
6634 Py_END_ALLOW_THREADS
6635 if (fd < 0)
6636 return posix_error_with_allocated_filename(file);
6637 PyMem_Free(file);
6638 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006639}
6640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006641
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006642PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006643"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006645
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006646/*
6647The underscore at end of function name avoids a name clash with the libc
6648function posix_close.
6649*/
Barry Warsaw53699e91996-12-10 23:23:01 +00006650static PyObject *
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05006651posix_close_(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006652{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006653 int fd, res;
6654 if (!PyArg_ParseTuple(args, "i:close", &fd))
6655 return NULL;
6656 if (!_PyVerify_fd(fd))
6657 return posix_error();
6658 Py_BEGIN_ALLOW_THREADS
6659 res = close(fd);
6660 Py_END_ALLOW_THREADS
6661 if (res < 0)
6662 return posix_error();
6663 Py_INCREF(Py_None);
6664 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006665}
6666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006667
Victor Stinnerd6f85422010-05-05 23:33:33 +00006668PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006669"closerange(fd_low, fd_high)\n\n\
6670Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6671
6672static PyObject *
6673posix_closerange(PyObject *self, PyObject *args)
6674{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006675 int fd_from, fd_to, i;
6676 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6677 return NULL;
6678 Py_BEGIN_ALLOW_THREADS
6679 for (i = fd_from; i < fd_to; i++)
6680 if (_PyVerify_fd(i))
6681 close(i);
6682 Py_END_ALLOW_THREADS
6683 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006684}
6685
6686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006688"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006690
Barry Warsaw53699e91996-12-10 23:23:01 +00006691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006692posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006693{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006694 int fd;
6695 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6696 return NULL;
6697 if (!_PyVerify_fd(fd))
6698 return posix_error();
6699 Py_BEGIN_ALLOW_THREADS
6700 fd = dup(fd);
6701 Py_END_ALLOW_THREADS
6702 if (fd < 0)
6703 return posix_error();
6704 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006705}
6706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006707
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006708PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006709"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006710Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006711
Barry Warsaw53699e91996-12-10 23:23:01 +00006712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006713posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006714{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006715 int fd, fd2, res;
6716 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6717 return NULL;
6718 if (!_PyVerify_fd_dup2(fd, fd2))
6719 return posix_error();
6720 Py_BEGIN_ALLOW_THREADS
6721 res = dup2(fd, fd2);
6722 Py_END_ALLOW_THREADS
6723 if (res < 0)
6724 return posix_error();
6725 Py_INCREF(Py_None);
6726 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006727}
6728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006730PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006731"lseek(fd, pos, how) -> newpos\n\n\
Georg Brandl6d076412014-03-11 10:28:56 +01006732Set the current position of a file descriptor.\n\
6733Return the new cursor position in bytes, starting from the beginning.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006734
Barry Warsaw53699e91996-12-10 23:23:01 +00006735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006736posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006737{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006738 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006739#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006740 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006741#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006742 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006743#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006744 PyObject *posobj;
6745 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6746 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006747#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006748 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6749 switch (how) {
6750 case 0: how = SEEK_SET; break;
6751 case 1: how = SEEK_CUR; break;
6752 case 2: how = SEEK_END; break;
6753 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006754#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006755
6756#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006757 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006758#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006759 pos = PyLong_Check(posobj) ?
6760 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006761#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006762 if (PyErr_Occurred())
6763 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006764
Victor Stinnerd6f85422010-05-05 23:33:33 +00006765 if (!_PyVerify_fd(fd))
6766 return posix_error();
6767 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006768#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006769 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006770#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006771 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006772#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006773 Py_END_ALLOW_THREADS
6774 if (res < 0)
6775 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006776
6777#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006778 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006779#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006780 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006781#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006782}
6783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006784
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006785PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006786"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006787Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006788
Barry Warsaw53699e91996-12-10 23:23:01 +00006789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006790posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006791{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006792 int fd, size, n;
6793 PyObject *buffer;
6794 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6795 return NULL;
6796 if (size < 0) {
6797 errno = EINVAL;
6798 return posix_error();
6799 }
6800 buffer = PyString_FromStringAndSize((char *)NULL, size);
6801 if (buffer == NULL)
6802 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006803 if (!_PyVerify_fd(fd)) {
6804 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006805 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006806 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006807 Py_BEGIN_ALLOW_THREADS
6808 n = read(fd, PyString_AsString(buffer), size);
6809 Py_END_ALLOW_THREADS
6810 if (n < 0) {
6811 Py_DECREF(buffer);
6812 return posix_error();
6813 }
6814 if (n != size)
6815 _PyString_Resize(&buffer, n);
6816 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006817}
6818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006819
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006821"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006822Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006823
Barry Warsaw53699e91996-12-10 23:23:01 +00006824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006825posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006826{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006827 Py_buffer pbuf;
6828 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006829 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006830
Victor Stinnerd6f85422010-05-05 23:33:33 +00006831 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6832 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006833 if (!_PyVerify_fd(fd)) {
6834 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006835 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006836 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006837 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006838 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006839#if defined(MS_WIN64) || defined(MS_WINDOWS)
6840 if (len > INT_MAX)
6841 len = INT_MAX;
6842 size = write(fd, pbuf.buf, (int)len);
6843#else
6844 size = write(fd, pbuf.buf, len);
6845#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006846 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006847 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006848 if (size < 0)
6849 return posix_error();
6850 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006851}
6852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006854PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006855"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006857
Barry Warsaw53699e91996-12-10 23:23:01 +00006858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006859posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006860{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006861 int fd;
6862 STRUCT_STAT st;
6863 int res;
6864 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6865 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006866#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006867 /* on OpenVMS we must ensure that all bytes are written to the file */
6868 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006869#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006870 if (!_PyVerify_fd(fd))
6871 return posix_error();
6872 Py_BEGIN_ALLOW_THREADS
6873 res = FSTAT(fd, &st);
6874 Py_END_ALLOW_THREADS
6875 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006876#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006877 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006878#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006879 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006880#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006881 }
Tim Peters5aa91602002-01-30 05:46:57 +00006882
Victor Stinnerd6f85422010-05-05 23:33:33 +00006883 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006884}
6885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006886
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006887PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006888"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006889Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006890
Barry Warsaw53699e91996-12-10 23:23:01 +00006891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006892posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006893{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006894 int fd;
6895 char *orgmode = "r";
6896 int bufsize = -1;
6897 FILE *fp;
6898 PyObject *f;
6899 char *mode;
6900 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6901 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006902
Victor Stinnerd6f85422010-05-05 23:33:33 +00006903 /* Sanitize mode. See fileobject.c */
6904 mode = PyMem_MALLOC(strlen(orgmode)+3);
6905 if (!mode) {
6906 PyErr_NoMemory();
6907 return NULL;
6908 }
6909 strcpy(mode, orgmode);
6910 if (_PyFile_SanitizeMode(mode)) {
6911 PyMem_FREE(mode);
6912 return NULL;
6913 }
Benjamin Peterson02ab7a82014-04-09 15:40:18 -04006914 if (!_PyVerify_fd(fd)) {
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006915 PyMem_FREE(mode);
6916 return posix_error();
6917 }
6918#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
6919 {
6920 struct stat buf;
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006921 const char *msg;
6922 PyObject *exc;
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006923 if (fstat(fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
6924 PyMem_FREE(mode);
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006925 msg = strerror(EISDIR);
Benjamin Petersone3737542014-08-24 10:37:12 -05006926 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
Benjamin Peterson7fc8a102014-04-14 19:57:52 -04006927 EISDIR, msg, "<fdopen>");
6928 if (exc) {
6929 PyErr_SetObject(PyExc_IOError, exc);
6930 Py_DECREF(exc);
6931 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006932 return NULL;
6933 }
6934 }
6935#endif
Benjamin Petersond3035d52016-12-03 13:03:18 -08006936 /* The dummy filename used here must be kept in sync with the value
6937 tested against in gzip.GzipFile.__init__() - see issue #13781. */
6938 f = PyFile_FromFile(NULL, "<fdopen>", orgmode, fclose);
Benjamin Petersone95048e2016-12-03 13:05:40 -08006939 if (f == NULL) {
Benjamin Peterson9ea8faf2016-12-03 13:07:47 -08006940 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006941 return NULL;
Benjamin Petersone95048e2016-12-03 13:05:40 -08006942 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006943 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006944#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006945 if (mode[0] == 'a') {
6946 /* try to make sure the O_APPEND flag is set */
6947 int flags;
6948 flags = fcntl(fd, F_GETFL);
6949 if (flags != -1)
6950 fcntl(fd, F_SETFL, flags | O_APPEND);
6951 fp = fdopen(fd, mode);
6952 if (fp == NULL && flags != -1)
6953 /* restore old mode if fdopen failed */
6954 fcntl(fd, F_SETFL, flags);
6955 } else {
6956 fp = fdopen(fd, mode);
6957 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006958#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006959 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006960#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006961 Py_END_ALLOW_THREADS
6962 PyMem_FREE(mode);
Benjamin Petersond3035d52016-12-03 13:03:18 -08006963 if (fp == NULL) {
6964 Py_DECREF(f);
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006965 return posix_error();
Benjamin Petersond3035d52016-12-03 13:03:18 -08006966 }
Benjamin Peterson5c863bf2014-04-14 19:45:46 -04006967 /* We now know we will succeed, so initialize the file object. */
6968 ((PyFileObject *)f)->f_fp = fp;
6969 PyFile_SetBufSize(f, bufsize);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006970 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006971}
6972
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006973PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006974"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006975Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006976connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006977
6978static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006979posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006980{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006981 int fd;
6982 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6983 return NULL;
6984 if (!_PyVerify_fd(fd))
6985 return PyBool_FromLong(0);
6986 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006987}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006988
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006989#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006990PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006991"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006992Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006993
Barry Warsaw53699e91996-12-10 23:23:01 +00006994static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006995posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006996{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006997#if defined(PYOS_OS2)
6998 HFILE read, write;
6999 APIRET rc;
7000
Victor Stinnerd6f85422010-05-05 23:33:33 +00007001 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007002 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007003 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007004 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007005 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007006
7007 return Py_BuildValue("(ii)", read, write);
7008#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007009#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007010 int fds[2];
7011 int res;
7012 Py_BEGIN_ALLOW_THREADS
7013 res = pipe(fds);
7014 Py_END_ALLOW_THREADS
7015 if (res != 0)
7016 return posix_error();
7017 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007018#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00007019 HANDLE read, write;
7020 int read_fd, write_fd;
7021 BOOL ok;
7022 Py_BEGIN_ALLOW_THREADS
7023 ok = CreatePipe(&read, &write, NULL, 0);
7024 Py_END_ALLOW_THREADS
7025 if (!ok)
7026 return win32_error("CreatePipe", NULL);
7027 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
7028 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
7029 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007030#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007031#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00007032}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007033#endif /* HAVE_PIPE */
7034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007035
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007036#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007037PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007038"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007039Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007040
Barry Warsaw53699e91996-12-10 23:23:01 +00007041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007042posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007043{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007044 char *filename;
7045 int mode = 0666;
7046 int res;
7047 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
7048 return NULL;
7049 Py_BEGIN_ALLOW_THREADS
7050 res = mkfifo(filename, mode);
7051 Py_END_ALLOW_THREADS
7052 if (res < 0)
7053 return posix_error();
7054 Py_INCREF(Py_None);
7055 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007056}
7057#endif
7058
7059
Neal Norwitz11690112002-07-30 01:08:28 +00007060#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007061PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00007062"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007063Create a filesystem node (file, device special file or named pipe)\n\
7064named filename. mode specifies both the permissions to use and the\n\
7065type of node to be created, being combined (bitwise OR) with one of\n\
7066S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007067device defines the newly created device special file (probably using\n\
7068os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007069
7070
7071static PyObject *
7072posix_mknod(PyObject *self, PyObject *args)
7073{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007074 char *filename;
7075 int mode = 0600;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007076 dev_t device = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007077 int res;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007078 if (!PyArg_ParseTuple(args, "s|iO&:mknod",
7079 &filename, &mode,
7080 _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007081 return NULL;
7082 Py_BEGIN_ALLOW_THREADS
7083 res = mknod(filename, mode, device);
7084 Py_END_ALLOW_THREADS
7085 if (res < 0)
7086 return posix_error();
7087 Py_INCREF(Py_None);
7088 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007089}
7090#endif
7091
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007092#ifdef HAVE_DEVICE_MACROS
7093PyDoc_STRVAR(posix_major__doc__,
7094"major(device) -> major number\n\
7095Extracts a device major number from a raw device number.");
7096
7097static PyObject *
7098posix_major(PyObject *self, PyObject *args)
7099{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007100 dev_t device;
7101 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007102 return NULL;
7103 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007104}
7105
7106PyDoc_STRVAR(posix_minor__doc__,
7107"minor(device) -> minor number\n\
7108Extracts a device minor number from a raw device number.");
7109
7110static PyObject *
7111posix_minor(PyObject *self, PyObject *args)
7112{
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007113 dev_t device;
7114 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007115 return NULL;
7116 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007117}
7118
7119PyDoc_STRVAR(posix_makedev__doc__,
7120"makedev(major, minor) -> device number\n\
7121Composes a raw device number from the major and minor device numbers.");
7122
7123static PyObject *
7124posix_makedev(PyObject *self, PyObject *args)
7125{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007126 int major, minor;
7127 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
7128 return NULL;
Serhiy Storchaka2098d612015-01-18 11:11:25 +02007129 return _PyInt_FromDev(makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007130}
7131#endif /* device macros */
7132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007133
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007134#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007135PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007136"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007137Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007138
Barry Warsaw53699e91996-12-10 23:23:01 +00007139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007140posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007141{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007142 int fd;
7143 off_t length;
7144 int res;
7145 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007146
Victor Stinnerd6f85422010-05-05 23:33:33 +00007147 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
7148 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007149
7150#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007151 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007152#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007153 length = PyLong_Check(lenobj) ?
7154 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007155#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007156 if (PyErr_Occurred())
7157 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007158
Victor Stinnerd6f85422010-05-05 23:33:33 +00007159 Py_BEGIN_ALLOW_THREADS
7160 res = ftruncate(fd, length);
7161 Py_END_ALLOW_THREADS
7162 if (res < 0)
7163 return posix_error();
7164 Py_INCREF(Py_None);
7165 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007166}
7167#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00007168
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007169#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007170PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007171"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007172Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007173
Fred Drake762e2061999-08-26 17:23:54 +00007174/* Save putenv() parameters as values here, so we can collect them when they
7175 * get re-set with another call for the same key. */
7176static PyObject *posix_putenv_garbage;
7177
Tim Peters5aa91602002-01-30 05:46:57 +00007178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007179posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007180{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007181 char *s1, *s2;
7182 char *newenv;
7183 PyObject *newstr;
7184 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007185
Victor Stinnerd6f85422010-05-05 23:33:33 +00007186 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
7187 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007188
7189#if defined(PYOS_OS2)
7190 if (stricmp(s1, "BEGINLIBPATH") == 0) {
7191 APIRET rc;
7192
Guido van Rossumd48f2521997-12-05 22:19:34 +00007193 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
7194 if (rc != NO_ERROR)
7195 return os2_error(rc);
7196
7197 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
7198 APIRET rc;
7199
Guido van Rossumd48f2521997-12-05 22:19:34 +00007200 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
7201 if (rc != NO_ERROR)
7202 return os2_error(rc);
7203 } else {
7204#endif
7205
Serhiy Storchaka787826c2017-06-25 09:50:00 +03007206 /* Search from index 1 because on Windows starting '=' is allowed for
7207 defining hidden environment variables. */
7208 if (*s1 == '\0' || strchr(s1 + 1, '=') != NULL) {
7209 PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
7210 return NULL;
7211 }
7212
Victor Stinnerd6f85422010-05-05 23:33:33 +00007213 /* XXX This can leak memory -- not easy to fix :-( */
7214 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007215#ifdef MS_WINDOWS
7216 if (_MAX_ENV < (len - 1)) {
7217 PyErr_Format(PyExc_ValueError,
7218 "the environment variable is longer than %u bytes",
7219 _MAX_ENV);
7220 return NULL;
7221 }
7222#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007223 /* len includes space for a trailing \0; the size arg to
7224 PyString_FromStringAndSize does not count that */
7225 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7226 if (newstr == NULL)
7227 return PyErr_NoMemory();
7228 newenv = PyString_AS_STRING(newstr);
7229 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7230 if (putenv(newenv)) {
7231 Py_DECREF(newstr);
7232 posix_error();
7233 return NULL;
7234 }
7235 /* Install the first arg and newstr in posix_putenv_garbage;
7236 * this will cause previous value to be collected. This has to
7237 * happen after the real putenv() call because the old value
7238 * was still accessible until then. */
7239 if (PyDict_SetItem(posix_putenv_garbage,
7240 PyTuple_GET_ITEM(args, 0), newstr)) {
7241 /* really not much we can do; just leak */
7242 PyErr_Clear();
7243 }
7244 else {
7245 Py_DECREF(newstr);
7246 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007247
7248#if defined(PYOS_OS2)
7249 }
7250#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007251 Py_INCREF(Py_None);
7252 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007253}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007254#endif /* putenv */
7255
Guido van Rossumc524d952001-10-19 01:31:59 +00007256#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007257PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007258"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007259Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007260
7261static PyObject *
7262posix_unsetenv(PyObject *self, PyObject *args)
7263{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007264 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007265#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007266 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007267#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007268
Victor Stinnerd6f85422010-05-05 23:33:33 +00007269 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7270 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007271
Charles-François Natali93a11752011-11-27 13:01:35 +01007272#ifdef HAVE_BROKEN_UNSETENV
7273 unsetenv(s1);
7274#else
Victor Stinner53853c32011-11-22 22:20:13 +01007275 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007276 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007277 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007278#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007279
Victor Stinnerd6f85422010-05-05 23:33:33 +00007280 /* Remove the key from posix_putenv_garbage;
7281 * this will cause it to be collected. This has to
7282 * happen after the real unsetenv() call because the
7283 * old value was still accessible until then.
7284 */
7285 if (PyDict_DelItem(posix_putenv_garbage,
7286 PyTuple_GET_ITEM(args, 0))) {
7287 /* really not much we can do; just leak */
7288 PyErr_Clear();
7289 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007290
Victor Stinnerd6f85422010-05-05 23:33:33 +00007291 Py_INCREF(Py_None);
7292 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007293}
7294#endif /* unsetenv */
7295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007296PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007297"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007298Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007299
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007301posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007302{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007303 int code;
7304 char *message;
7305 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7306 return NULL;
7307 message = strerror(code);
7308 if (message == NULL) {
7309 PyErr_SetString(PyExc_ValueError,
7310 "strerror() argument out of range");
7311 return NULL;
7312 }
7313 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007314}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007315
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007316
Guido van Rossumc9641791998-08-04 15:26:23 +00007317#ifdef HAVE_SYS_WAIT_H
7318
Fred Drake106c1a02002-04-23 15:58:02 +00007319#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007320PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007321"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007322Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007323
7324static PyObject *
7325posix_WCOREDUMP(PyObject *self, PyObject *args)
7326{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007327 WAIT_TYPE status;
7328 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007329
Victor Stinnerd6f85422010-05-05 23:33:33 +00007330 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7331 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007332
Victor Stinnerd6f85422010-05-05 23:33:33 +00007333 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007334}
7335#endif /* WCOREDUMP */
7336
7337#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007338PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007339"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007340Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007341job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007342
7343static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007344posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007345{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007346 WAIT_TYPE status;
7347 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007348
Victor Stinnerd6f85422010-05-05 23:33:33 +00007349 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7350 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007351
Victor Stinnerd6f85422010-05-05 23:33:33 +00007352 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007353}
7354#endif /* WIFCONTINUED */
7355
Guido van Rossumc9641791998-08-04 15:26:23 +00007356#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007357PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007358"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007359Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007360
7361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007362posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007363{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007364 WAIT_TYPE status;
7365 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007366
Victor Stinnerd6f85422010-05-05 23:33:33 +00007367 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7368 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007369
Victor Stinnerd6f85422010-05-05 23:33:33 +00007370 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007371}
7372#endif /* WIFSTOPPED */
7373
7374#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007375PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007376"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007377Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007378
7379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007380posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007381{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007382 WAIT_TYPE status;
7383 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007384
Victor Stinnerd6f85422010-05-05 23:33:33 +00007385 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7386 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007387
Victor Stinnerd6f85422010-05-05 23:33:33 +00007388 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007389}
7390#endif /* WIFSIGNALED */
7391
7392#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007393PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007394"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007395Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007396system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007397
7398static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007399posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007400{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007401 WAIT_TYPE status;
7402 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007403
Victor Stinnerd6f85422010-05-05 23:33:33 +00007404 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7405 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007406
Victor Stinnerd6f85422010-05-05 23:33:33 +00007407 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007408}
7409#endif /* WIFEXITED */
7410
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007411#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007412PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007413"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007414Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007415
7416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007417posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007418{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007419 WAIT_TYPE status;
7420 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007421
Victor Stinnerd6f85422010-05-05 23:33:33 +00007422 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7423 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007424
Victor Stinnerd6f85422010-05-05 23:33:33 +00007425 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007426}
7427#endif /* WEXITSTATUS */
7428
7429#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007431"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007432Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007433value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007434
7435static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007436posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007437{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007438 WAIT_TYPE status;
7439 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007440
Victor Stinnerd6f85422010-05-05 23:33:33 +00007441 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7442 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007443
Victor Stinnerd6f85422010-05-05 23:33:33 +00007444 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007445}
7446#endif /* WTERMSIG */
7447
7448#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007449PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007450"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007451Return the signal that stopped the process that provided\n\
7452the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007453
7454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007455posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007456{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007457 WAIT_TYPE status;
7458 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007459
Victor Stinnerd6f85422010-05-05 23:33:33 +00007460 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7461 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007462
Victor Stinnerd6f85422010-05-05 23:33:33 +00007463 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007464}
7465#endif /* WSTOPSIG */
7466
7467#endif /* HAVE_SYS_WAIT_H */
7468
7469
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007470#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007471#ifdef _SCO_DS
7472/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7473 needed definitions in sys/statvfs.h */
7474#define _SVID3
7475#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007476#include <sys/statvfs.h>
7477
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007478static PyObject*
7479_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007480 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7481 if (v == NULL)
7482 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007483
7484#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007485 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7486 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7487 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7488 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7489 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7490 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7491 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7492 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7493 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7494 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007495#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007496 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7497 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7498 PyStructSequence_SET_ITEM(v, 2,
7499 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7500 PyStructSequence_SET_ITEM(v, 3,
7501 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7502 PyStructSequence_SET_ITEM(v, 4,
7503 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7504 PyStructSequence_SET_ITEM(v, 5,
7505 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7506 PyStructSequence_SET_ITEM(v, 6,
7507 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7508 PyStructSequence_SET_ITEM(v, 7,
7509 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7510 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7511 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007512#endif
7513
Victor Stinnerd6f85422010-05-05 23:33:33 +00007514 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007515}
7516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007517PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007518"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007519Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007520
7521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007522posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007523{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007524 int fd, res;
7525 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007526
Victor Stinnerd6f85422010-05-05 23:33:33 +00007527 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7528 return NULL;
7529 Py_BEGIN_ALLOW_THREADS
7530 res = fstatvfs(fd, &st);
7531 Py_END_ALLOW_THREADS
7532 if (res != 0)
7533 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007534
Victor Stinnerd6f85422010-05-05 23:33:33 +00007535 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007536}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007537#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007538
7539
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007540#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007541#include <sys/statvfs.h>
7542
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007543PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007544"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007545Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007546
7547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007548posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007549{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007550 char *path;
7551 int res;
7552 struct statvfs st;
7553 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7554 return NULL;
7555 Py_BEGIN_ALLOW_THREADS
7556 res = statvfs(path, &st);
7557 Py_END_ALLOW_THREADS
7558 if (res != 0)
7559 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007560
Victor Stinnerd6f85422010-05-05 23:33:33 +00007561 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007562}
7563#endif /* HAVE_STATVFS */
7564
7565
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007567PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007568"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007569Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007570The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007571or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572
7573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007574posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007575{
7576 PyObject *result = NULL;
7577 char *dir = NULL;
7578 char *pfx = NULL;
7579 char *name;
7580
7581 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007582 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007583
7584 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007585 "tempnam is a potential security risk to your program") < 0)
7586 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007587
Antoine Pitroub0614612011-01-02 20:04:52 +00007588 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7589 "use the tempfile module", 1) < 0)
7590 return NULL;
7591
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007592#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007593 name = _tempnam(dir, pfx);
7594#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007595 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007596#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007597 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007598 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007599 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007600 free(name);
7601 return result;
7602}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007603#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007604
7605
7606#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007607PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007608"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007609Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007610
7611static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007612posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007613{
7614 FILE *fp;
7615
Antoine Pitroub0614612011-01-02 20:04:52 +00007616 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7617 "use the tempfile module", 1) < 0)
7618 return NULL;
7619
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007620 fp = tmpfile();
7621 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007622 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007623 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007624}
7625#endif
7626
7627
7628#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007629PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007630"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007631Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007632
7633static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007634posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007635{
7636 char buffer[L_tmpnam];
7637 char *name;
7638
Skip Montanaro95618b52001-08-18 18:52:10 +00007639 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007640 "tmpnam is a potential security risk to your program") < 0)
7641 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007642
Antoine Pitroub0614612011-01-02 20:04:52 +00007643 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7644 "use the tempfile module", 1) < 0)
7645 return NULL;
7646
Greg Wardb48bc172000-03-01 21:51:56 +00007647#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007648 name = tmpnam_r(buffer);
7649#else
7650 name = tmpnam(buffer);
7651#endif
7652 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007653 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007654#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007655 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007656#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007657 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007658#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007659 );
7660 PyErr_SetObject(PyExc_OSError, err);
7661 Py_XDECREF(err);
7662 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007663 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007664 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007665}
7666#endif
7667
7668
Fred Drakec9680921999-12-13 16:37:25 +00007669/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7670 * It maps strings representing configuration variable names to
7671 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007672 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007673 * rarely-used constants. There are three separate tables that use
7674 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007675 *
7676 * This code is always included, even if none of the interfaces that
7677 * need it are included. The #if hackery needed to avoid it would be
7678 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007679 */
7680struct constdef {
7681 char *name;
7682 long value;
7683};
7684
Fred Drake12c6e2d1999-12-14 21:25:03 +00007685static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007686conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007687 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007688{
7689 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007690 *valuep = PyInt_AS_LONG(arg);
7691 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007692 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007693 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007694 /* look up the value in the table using a binary search */
7695 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007696 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007697 size_t hi = tablesize;
7698 int cmp;
7699 char *confname = PyString_AS_STRING(arg);
7700 while (lo < hi) {
7701 mid = (lo + hi) / 2;
7702 cmp = strcmp(confname, table[mid].name);
7703 if (cmp < 0)
7704 hi = mid;
7705 else if (cmp > 0)
7706 lo = mid + 1;
7707 else {
7708 *valuep = table[mid].value;
7709 return 1;
7710 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007711 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007712 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007713 }
7714 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007715 PyErr_SetString(PyExc_TypeError,
7716 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007717 return 0;
7718}
7719
7720
7721#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7722static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007723#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007724 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007725#endif
7726#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007727 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007728#endif
Fred Drakec9680921999-12-13 16:37:25 +00007729#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007730 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007731#endif
7732#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007733 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007734#endif
7735#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007736 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007737#endif
7738#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007739 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007740#endif
7741#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007742 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007743#endif
7744#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007745 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007746#endif
7747#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007748 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007749#endif
7750#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007751 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007752#endif
7753#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007754 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007755#endif
7756#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007757 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007758#endif
7759#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007760 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007761#endif
7762#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007763 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007764#endif
7765#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007766 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007767#endif
7768#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007769 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007770#endif
7771#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007772 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007773#endif
7774};
7775
Fred Drakec9680921999-12-13 16:37:25 +00007776static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007777conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007778{
7779 return conv_confname(arg, valuep, posix_constants_pathconf,
7780 sizeof(posix_constants_pathconf)
7781 / sizeof(struct constdef));
7782}
7783#endif
7784
7785#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007786PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007787"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007788Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007789If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007790
7791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007792posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007793{
7794 PyObject *result = NULL;
7795 int name, fd;
7796
Fred Drake12c6e2d1999-12-14 21:25:03 +00007797 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7798 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007799 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007800
Stefan Krah93f7a322010-11-26 17:35:50 +00007801 errno = 0;
7802 limit = fpathconf(fd, name);
7803 if (limit == -1 && errno != 0)
7804 posix_error();
7805 else
7806 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007807 }
7808 return result;
7809}
7810#endif
7811
7812
7813#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007814PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007815"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007816Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007817If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007818
7819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007820posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007821{
7822 PyObject *result = NULL;
7823 int name;
7824 char *path;
7825
7826 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7827 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007828 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007829
Victor Stinnerd6f85422010-05-05 23:33:33 +00007830 errno = 0;
7831 limit = pathconf(path, name);
7832 if (limit == -1 && errno != 0) {
7833 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007834 /* could be a path or name problem */
7835 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007836 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007837 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007838 }
7839 else
7840 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007841 }
7842 return result;
7843}
7844#endif
7845
7846#ifdef HAVE_CONFSTR
7847static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007848#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007850#endif
7851#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007853#endif
7854#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007856#endif
7857#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007859#endif
7860#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007862#endif
Fred Drakec9680921999-12-13 16:37:25 +00007863#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007865#endif
7866#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
7869#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
7881#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007883#endif
7884#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007886#endif
Fred Draked86ed291999-12-15 15:34:33 +00007887#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007889#endif
Fred Drakec9680921999-12-13 16:37:25 +00007890#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007892#endif
Fred Draked86ed291999-12-15 15:34:33 +00007893#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007895#endif
7896#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007898#endif
7899#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007901#endif
7902#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007904#endif
Fred Drakec9680921999-12-13 16:37:25 +00007905#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
7908#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007910#endif
7911#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007913#endif
7914#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007916#endif
7917#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
7920#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007922#endif
7923#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
7926#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007928#endif
7929#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
7932#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007934#endif
7935#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007937#endif
7938#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007940#endif
7941#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007943#endif
7944#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007946#endif
7947#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007949#endif
7950#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007951 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007952#endif
Fred Draked86ed291999-12-15 15:34:33 +00007953#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007954 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007955#endif
7956#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007957 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007958#endif
7959#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007960 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007961#endif
7962#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007963 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007964#endif
7965#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007966 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007967#endif
7968#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007969 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007970#endif
7971#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007973#endif
7974#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007975 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007976#endif
7977#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007979#endif
7980#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007982#endif
7983#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007984 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007985#endif
7986#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007987 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007988#endif
7989#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007990 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007991#endif
Fred Drakec9680921999-12-13 16:37:25 +00007992};
7993
7994static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007995conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007996{
7997 return conv_confname(arg, valuep, posix_constants_confstr,
7998 sizeof(posix_constants_confstr)
7999 / sizeof(struct constdef));
8000}
8001
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008002PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008003"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008004Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008005
8006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008007posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008008{
8009 PyObject *result = NULL;
8010 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00008011 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00008012
8013 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008014 int len;
Fred Drakec9680921999-12-13 16:37:25 +00008015
Victor Stinnerd6f85422010-05-05 23:33:33 +00008016 errno = 0;
8017 len = confstr(name, buffer, sizeof(buffer));
8018 if (len == 0) {
8019 if (errno) {
8020 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00008021 }
8022 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008023 result = Py_None;
8024 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00008025 }
8026 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00008027 else {
8028 if ((unsigned int)len >= sizeof(buffer)) {
8029 result = PyString_FromStringAndSize(NULL, len-1);
8030 if (result != NULL)
8031 confstr(name, PyString_AS_STRING(result), len);
8032 }
8033 else
8034 result = PyString_FromStringAndSize(buffer, len-1);
8035 }
8036 }
Fred Drakec9680921999-12-13 16:37:25 +00008037 return result;
8038}
8039#endif
8040
8041
8042#ifdef HAVE_SYSCONF
8043static struct constdef posix_constants_sysconf[] = {
8044#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008045 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00008046#endif
8047#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00008048 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00008049#endif
8050#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008051 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008052#endif
8053#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008054 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008055#endif
8056#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008057 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008058#endif
8059#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008060 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00008061#endif
8062#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008063 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00008064#endif
8065#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008066 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00008067#endif
8068#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008069 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00008070#endif
8071#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008072 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008073#endif
Fred Draked86ed291999-12-15 15:34:33 +00008074#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008075 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00008076#endif
8077#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008078 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00008079#endif
Fred Drakec9680921999-12-13 16:37:25 +00008080#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008081 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008082#endif
Fred Drakec9680921999-12-13 16:37:25 +00008083#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008084 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008085#endif
8086#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008087 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008088#endif
8089#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008090 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008091#endif
8092#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008093 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008094#endif
8095#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008096 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008097#endif
Fred Draked86ed291999-12-15 15:34:33 +00008098#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008099 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00008100#endif
Fred Drakec9680921999-12-13 16:37:25 +00008101#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008102 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008103#endif
8104#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008105 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008106#endif
8107#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008108 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008109#endif
8110#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008111 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008112#endif
8113#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008114 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008115#endif
Fred Draked86ed291999-12-15 15:34:33 +00008116#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008117 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00008118#endif
Fred Drakec9680921999-12-13 16:37:25 +00008119#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008120 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008121#endif
8122#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008123 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008124#endif
8125#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008126 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008127#endif
8128#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008129 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008130#endif
8131#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008132 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008133#endif
8134#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008135 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00008136#endif
8137#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008138 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008139#endif
8140#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008141 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008142#endif
8143#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008144 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008145#endif
8146#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008147 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008148#endif
8149#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008150 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008151#endif
8152#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008153 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008154#endif
8155#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008156 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008157#endif
8158#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008159 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008160#endif
8161#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008162 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008163#endif
8164#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008165 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008166#endif
8167#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008168 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00008169#endif
8170#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008171 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008172#endif
8173#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008174 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008175#endif
8176#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008177 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00008178#endif
8179#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008180 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00008181#endif
8182#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008183 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00008184#endif
8185#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00008186 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00008187#endif
Fred Draked86ed291999-12-15 15:34:33 +00008188#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008189 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00008190#endif
Fred Drakec9680921999-12-13 16:37:25 +00008191#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008192 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008193#endif
8194#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008195 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008196#endif
8197#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008198 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008199#endif
Fred Draked86ed291999-12-15 15:34:33 +00008200#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008201 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00008202#endif
Fred Drakec9680921999-12-13 16:37:25 +00008203#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008204 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00008205#endif
Fred Draked86ed291999-12-15 15:34:33 +00008206#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008207 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00008208#endif
8209#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008210 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00008211#endif
Fred Drakec9680921999-12-13 16:37:25 +00008212#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008213 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008214#endif
8215#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008216 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008217#endif
8218#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008219 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008220#endif
8221#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008222 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008223#endif
Fred Draked86ed291999-12-15 15:34:33 +00008224#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008225 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008226#endif
Fred Drakec9680921999-12-13 16:37:25 +00008227#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008228 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008229#endif
8230#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008231 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008232#endif
8233#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008234 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008235#endif
8236#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008237 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008238#endif
8239#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008240 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008241#endif
8242#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008243 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008244#endif
8245#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008246 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008247#endif
Fred Draked86ed291999-12-15 15:34:33 +00008248#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008249 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008250#endif
Fred Drakec9680921999-12-13 16:37:25 +00008251#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008252 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008253#endif
8254#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008255 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
Fred Draked86ed291999-12-15 15:34:33 +00008257#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008258 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008259#endif
Fred Drakec9680921999-12-13 16:37:25 +00008260#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008261 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008264 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008267 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
8269#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008270 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008271#endif
8272#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008273 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008274#endif
8275#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008276 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008277#endif
8278#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008279 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
8281#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008282 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008283#endif
8284#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008285 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008286#endif
Fred Draked86ed291999-12-15 15:34:33 +00008287#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008288 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008289#endif
8290#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008291 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008292#endif
Fred Drakec9680921999-12-13 16:37:25 +00008293#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008294 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008295#endif
8296#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008297 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008298#endif
8299#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008300 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008301#endif
8302#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008303 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008304#endif
8305#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008306 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008307#endif
8308#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008309 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008310#endif
8311#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008312 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008313#endif
8314#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008315 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008316#endif
8317#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008318 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008319#endif
8320#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008321 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008322#endif
8323#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008324 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008325#endif
8326#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008327 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008328#endif
8329#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008330 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008331#endif
8332#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008333 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008334#endif
8335#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008336 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008337#endif
8338#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008339 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008340#endif
8341#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008342 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008343#endif
8344#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008345 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008346#endif
8347#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008348 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008349#endif
8350#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008351 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008352#endif
8353#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008354 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008355#endif
8356#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008357 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008358#endif
8359#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008360 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008361#endif
8362#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008363 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008364#endif
8365#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008366 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008367#endif
8368#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008369 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008370#endif
8371#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008372 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008373#endif
8374#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008375 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008376#endif
8377#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008378 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008379#endif
8380#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008381 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008382#endif
8383#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008384 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008385#endif
8386#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008387 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008388#endif
8389#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008390 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008391#endif
8392#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008393 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008394#endif
8395#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008396 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008397#endif
Fred Draked86ed291999-12-15 15:34:33 +00008398#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008399 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008400#endif
Fred Drakec9680921999-12-13 16:37:25 +00008401#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008402 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008403#endif
8404#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008405 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008406#endif
8407#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008408 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008409#endif
8410#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008411 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008412#endif
8413#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008414 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008415#endif
8416#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008417 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008418#endif
8419#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008420 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008421#endif
8422#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008423 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008424#endif
8425#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008426 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008427#endif
8428#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008429 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008430#endif
8431#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008432 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008433#endif
8434#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008435 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008436#endif
8437#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008438 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008439#endif
8440#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008441 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008442#endif
8443#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008444 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008445#endif
8446#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008447 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008448#endif
8449#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008450 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008451#endif
8452#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008453 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008454#endif
8455#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008456 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008457#endif
8458#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008459 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008460#endif
8461#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008462 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008463#endif
8464#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008465 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008466#endif
8467#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008469#endif
8470#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008471 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008472#endif
8473#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008474 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008475#endif
8476#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008477 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008478#endif
8479#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008480 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008481#endif
8482#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008483 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008484#endif
8485#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008486 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008487#endif
8488#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008489 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008490#endif
8491#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008492 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008493#endif
8494#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008495 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008496#endif
8497#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008498 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008499#endif
8500#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008501 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008502#endif
8503#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008504 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008505#endif
8506#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008507 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008508#endif
8509#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008510 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008511#endif
8512#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008513 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008514#endif
8515#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008516 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008517#endif
8518#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008519 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008520#endif
8521#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008522 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008523#endif
8524#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008525 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008526#endif
8527#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008528 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008529#endif
8530#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008531 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008532#endif
8533#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008534 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008535#endif
8536};
8537
8538static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008539conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008540{
8541 return conv_confname(arg, valuep, posix_constants_sysconf,
8542 sizeof(posix_constants_sysconf)
8543 / sizeof(struct constdef));
8544}
8545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008546PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008547"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008548Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008549
8550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008551posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008552{
8553 PyObject *result = NULL;
8554 int name;
8555
8556 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008557 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008558
Victor Stinner862490a2010-05-06 00:03:44 +00008559 errno = 0;
8560 value = sysconf(name);
8561 if (value == -1 && errno != 0)
8562 posix_error();
8563 else
8564 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008565 }
8566 return result;
8567}
8568#endif
8569
8570
Fred Drakebec628d1999-12-15 18:31:10 +00008571/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka0f8f7842014-12-01 18:16:30 +02008572 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +00008573 * the exported dictionaries that are used to publish information about the
8574 * names available on the host platform.
8575 *
8576 * Sorting the table at runtime ensures that the table is properly ordered
8577 * when used, even for platforms we're not able to test on. It also makes
8578 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008579 */
Fred Drakebec628d1999-12-15 18:31:10 +00008580
8581static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008582cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008583{
8584 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008585 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008586 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008587 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008588
8589 return strcmp(c1->name, c2->name);
8590}
8591
8592static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008593setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008594 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008595{
Fred Drakebec628d1999-12-15 18:31:10 +00008596 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008597 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008598 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8599 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008600 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008601 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008602
Barry Warsaw3155db32000-04-13 15:20:40 +00008603 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008604 PyObject *o = PyInt_FromLong(table[i].value);
8605 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8606 Py_XDECREF(o);
8607 Py_DECREF(d);
8608 return -1;
8609 }
8610 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008611 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008612 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008613}
8614
Fred Drakebec628d1999-12-15 18:31:10 +00008615/* Return -1 on failure, 0 on success. */
8616static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008617setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008618{
8619#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008620 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008621 sizeof(posix_constants_pathconf)
8622 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008623 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008624 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008625#endif
8626#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008627 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008628 sizeof(posix_constants_confstr)
8629 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008630 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008631 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008632#endif
8633#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008634 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008635 sizeof(posix_constants_sysconf)
8636 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008637 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008638 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008639#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008640 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008641}
Fred Draked86ed291999-12-15 15:34:33 +00008642
8643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008644PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008645"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008646Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008647in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008648
8649static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008650posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008652 abort();
8653 /*NOTREACHED*/
8654 Py_FatalError("abort() called from Python code didn't abort!");
8655 return NULL;
8656}
Fred Drakebec628d1999-12-15 18:31:10 +00008657
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008658#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008659PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008660"startfile(filepath [, operation]) - Start a file with its associated\n\
8661application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008662\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008663When \"operation\" is not specified or \"open\", this acts like\n\
8664double-clicking the file in Explorer, or giving the file name as an\n\
8665argument to the DOS \"start\" command: the file is opened with whatever\n\
8666application (if any) its extension is associated.\n\
8667When another \"operation\" is given, it specifies what should be done with\n\
8668the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008669\n\
8670startfile returns as soon as the associated application is launched.\n\
8671There is no option to wait for the application to close, and no way\n\
8672to retrieve the application's exit status.\n\
8673\n\
8674The filepath is relative to the current directory. If you want to use\n\
8675an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008676the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008677
8678static PyObject *
8679win32_startfile(PyObject *self, PyObject *args)
8680{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008681 char *filepath;
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008682 Py_UNICODE *wpath;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008683 char *operation = NULL;
8684 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008685
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008686 PyObject *woperation = NULL;
8687 if (!PyArg_ParseTuple(args, "u|s:startfile",
8688 &wpath, &operation)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008689 PyErr_Clear();
8690 goto normal;
8691 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008692
Victor Stinnerd6f85422010-05-05 23:33:33 +00008693 if (operation) {
8694 woperation = PyUnicode_DecodeASCII(operation,
8695 strlen(operation), NULL);
8696 if (!woperation) {
8697 PyErr_Clear();
8698 operation = NULL;
8699 goto normal;
8700 }
8701 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008702
Victor Stinnerd6f85422010-05-05 23:33:33 +00008703 Py_BEGIN_ALLOW_THREADS
8704 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008705 wpath,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008706 NULL, NULL, SW_SHOWNORMAL);
8707 Py_END_ALLOW_THREADS
8708
8709 Py_XDECREF(woperation);
8710 if (rc <= (HINSTANCE)32) {
Serhiy Storchaka3c9ce742016-07-01 23:34:44 +03008711 PyObject *errval = win32_error_unicode("startfile", wpath);
Victor Stinnerd6f85422010-05-05 23:33:33 +00008712 return errval;
8713 }
8714 Py_INCREF(Py_None);
8715 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008716
8717normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008718 if (!PyArg_ParseTuple(args, "et|s:startfile",
8719 Py_FileSystemDefaultEncoding, &filepath,
8720 &operation))
8721 return NULL;
8722 Py_BEGIN_ALLOW_THREADS
8723 rc = ShellExecute((HWND)0, operation, filepath,
8724 NULL, NULL, SW_SHOWNORMAL);
8725 Py_END_ALLOW_THREADS
8726 if (rc <= (HINSTANCE)32) {
8727 PyObject *errval = win32_error("startfile", filepath);
8728 PyMem_Free(filepath);
8729 return errval;
8730 }
8731 PyMem_Free(filepath);
8732 Py_INCREF(Py_None);
8733 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008734}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008735#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008736
Martin v. Löwis438b5342002-12-27 10:16:42 +00008737#ifdef HAVE_GETLOADAVG
8738PyDoc_STRVAR(posix_getloadavg__doc__,
8739"getloadavg() -> (float, float, float)\n\n\
8740Return the number of processes in the system run queue averaged over\n\
8741the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8742was unobtainable");
8743
8744static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008745posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008746{
8747 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008748 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008749 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8750 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008751 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008752 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008753}
8754#endif
8755
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008756PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008757"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008758Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008759
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008760static PyObject *
8761posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008762{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008763 Py_ssize_t size;
8764 PyObject *result;
8765 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008766
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008767 /* Read arguments */
8768 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008769 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008770 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008771 return PyErr_Format(PyExc_ValueError,
8772 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008773 result = PyBytes_FromStringAndSize(NULL, size);
8774 if (result == NULL)
8775 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008776
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008777 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8778 PyBytes_GET_SIZE(result));
8779 if (ret == -1) {
8780 Py_DECREF(result);
8781 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008782 }
8783 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008784}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008785
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008786#ifdef HAVE_SETRESUID
8787PyDoc_STRVAR(posix_setresuid__doc__,
8788"setresuid(ruid, euid, suid)\n\n\
8789Set the current process's real, effective, and saved user ids.");
8790
8791static PyObject*
8792posix_setresuid (PyObject *self, PyObject *args)
8793{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008794 uid_t ruid, euid, suid;
8795 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid",
8796 _Py_Uid_Converter, &ruid,
8797 _Py_Uid_Converter, &euid,
8798 _Py_Uid_Converter, &suid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008799 return NULL;
8800 if (setresuid(ruid, euid, suid) < 0)
8801 return posix_error();
8802 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008803}
8804#endif
8805
8806#ifdef HAVE_SETRESGID
8807PyDoc_STRVAR(posix_setresgid__doc__,
8808"setresgid(rgid, egid, sgid)\n\n\
8809Set the current process's real, effective, and saved group ids.");
8810
8811static PyObject*
8812posix_setresgid (PyObject *self, PyObject *args)
8813{
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008814 gid_t rgid, egid, sgid;
8815 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid",
8816 _Py_Gid_Converter, &rgid,
8817 _Py_Gid_Converter, &egid,
8818 _Py_Gid_Converter, &sgid))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008819 return NULL;
8820 if (setresgid(rgid, egid, sgid) < 0)
8821 return posix_error();
8822 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008823}
8824#endif
8825
8826#ifdef HAVE_GETRESUID
8827PyDoc_STRVAR(posix_getresuid__doc__,
8828"getresuid() -> (ruid, euid, suid)\n\n\
8829Get tuple of the current process's real, effective, and saved user ids.");
8830
8831static PyObject*
8832posix_getresuid (PyObject *self, PyObject *noargs)
8833{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008834 uid_t ruid, euid, suid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008835 if (getresuid(&ruid, &euid, &suid) < 0)
8836 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008837 return Py_BuildValue("(NNN)", _PyInt_FromUid(ruid),
8838 _PyInt_FromUid(euid),
8839 _PyInt_FromUid(suid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008840}
8841#endif
8842
8843#ifdef HAVE_GETRESGID
8844PyDoc_STRVAR(posix_getresgid__doc__,
8845"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008846Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008847
8848static PyObject*
8849posix_getresgid (PyObject *self, PyObject *noargs)
8850{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 uid_t rgid, egid, sgid;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008852 if (getresgid(&rgid, &egid, &sgid) < 0)
8853 return posix_error();
Serhiy Storchakada5c2a02013-02-12 09:27:53 +02008854 return Py_BuildValue("(NNN)", _PyInt_FromGid(rgid),
8855 _PyInt_FromGid(egid),
8856 _PyInt_FromGid(sgid));
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008857}
8858#endif
8859
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008860static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008862#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008864#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008866#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008867 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008868#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008869 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008870#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008871 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008872#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008873#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008874 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008875#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008876#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008877 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008878#endif /* HAVE_LCHMOD */
8879#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008881#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008882#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008883 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008884#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008885#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008887#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008888#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008889 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008890#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008891#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008893#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008894#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008896#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008897 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008898#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008899#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008900#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008902#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008903 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8904 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8905 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008906#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008908#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008909#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008910 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008911#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008912 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8913 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8914 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8915 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008916#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008917 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008918#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008919#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008920 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008921#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008922 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008923#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008925#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008926 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8927 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8928 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008929#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008930 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008931#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008933#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008934 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8935 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008936#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008937#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008938 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8939 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008940#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008941 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8942 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008943#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008944#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008945#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008946 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008947#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008948#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008949 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008950#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008951#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008953#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008954#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008955 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008956#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008957#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008958 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008959#endif /* HAVE_GETEGID */
8960#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008961 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008962#endif /* HAVE_GETEUID */
8963#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008964 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008965#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008966#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008967 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008968#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008969 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008970#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008971 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008972#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008973#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008974 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008975#endif /* HAVE_GETPPID */
8976#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008977 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008978#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008979#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008980 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008981#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008982#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008983 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008984#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008985#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008986 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008987#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008988#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008989 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008990#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008991#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008992 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008993#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008994 {"popen2", win32_popen2, METH_VARARGS},
8995 {"popen3", win32_popen3, METH_VARARGS},
8996 {"popen4", win32_popen4, METH_VARARGS},
8997 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8998 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008999#else
9000#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009001 {"popen2", os2emx_popen2, METH_VARARGS},
9002 {"popen3", os2emx_popen3, METH_VARARGS},
9003 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009004#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00009005#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009006#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009007#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009008 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009009#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009010#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009011 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009012#endif /* HAVE_SETEUID */
9013#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009014 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009015#endif /* HAVE_SETEGID */
9016#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009017 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009018#endif /* HAVE_SETREUID */
9019#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009020 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00009021#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009022#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009023 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009024#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009025#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009026 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00009027#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009028#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009029 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00009030#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00009031#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009032 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00009033#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009034#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009035 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009036#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00009037#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009038 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00009039#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00009040#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00009041 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009042#endif /* HAVE_WAIT3 */
9043#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00009044 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00009045#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00009046#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009047 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009048#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009049#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009050 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00009051#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009052#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009053 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009054#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009055#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009056 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009057#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009058#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009059 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009060#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00009061#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009062 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00009063#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00009064 {"open", posix_open, METH_VARARGS, posix_open__doc__},
Benjamin Peterson2748c5c2014-02-11 10:16:16 -05009065 {"close", posix_close_, METH_VARARGS, posix_close__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009066 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
9067 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
9068 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
9069 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
9070 {"read", posix_read, METH_VARARGS, posix_read__doc__},
9071 {"write", posix_write, METH_VARARGS, posix_write__doc__},
9072 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
9073 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
9074 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009075#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009076 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009077#endif
9078#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00009079 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009080#endif
Neal Norwitz11690112002-07-30 01:08:28 +00009081#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009082 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00009083#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009084#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009085 {"major", posix_major, METH_VARARGS, posix_major__doc__},
9086 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
9087 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00009088#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009089#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009090 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009091#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009092#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009093 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009094#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009095#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009096 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00009097#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009098 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009099#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00009101#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00009102#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009103 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009104#endif
9105#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009106 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00009107#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00009108#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009109#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00009110 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00009111#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009112#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009113 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00009114#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00009115#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009117#endif /* WIFSTOPPED */
9118#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009119 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009120#endif /* WIFSIGNALED */
9121#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009122 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009123#endif /* WIFEXITED */
9124#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009126#endif /* WEXITSTATUS */
9127#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009128 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009129#endif /* WTERMSIG */
9130#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009131 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00009132#endif /* WSTOPSIG */
9133#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009134#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009135 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009136#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00009137#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00009139#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00009140#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009141 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009142#endif
9143#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009145#endif
9146#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009147 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009148#endif
Fred Drakec9680921999-12-13 16:37:25 +00009149#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009150 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009151#endif
9152#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009153 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009154#endif
9155#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009156 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009157#endif
9158#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009159 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009160#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009161 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009162#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009163 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009164 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009165#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009166#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009167 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009168#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009169#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009170 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009171#endif
9172#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009173 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009174#endif
9175#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009176 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009177#endif
9178#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009179 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009180#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05009181 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00009182 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009183};
9184
9185
Barry Warsaw4a342091996-12-19 23:50:02 +00009186static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009187ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009188{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009189 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009190}
9191
Guido van Rossumd48f2521997-12-05 22:19:34 +00009192#if defined(PYOS_OS2)
9193/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009194static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009195{
9196 APIRET rc;
9197 ULONG values[QSV_MAX+1];
9198 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009199 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009200
9201 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009202 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009203 Py_END_ALLOW_THREADS
9204
9205 if (rc != NO_ERROR) {
9206 os2_error(rc);
9207 return -1;
9208 }
9209
Fred Drake4d1e64b2002-04-15 19:40:07 +00009210 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9211 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9212 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9213 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9214 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9215 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9216 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009217
9218 switch (values[QSV_VERSION_MINOR]) {
9219 case 0: ver = "2.00"; break;
9220 case 10: ver = "2.10"; break;
9221 case 11: ver = "2.11"; break;
9222 case 30: ver = "3.00"; break;
9223 case 40: ver = "4.00"; break;
9224 case 50: ver = "5.00"; break;
9225 default:
Tim Peters885d4572001-11-28 20:27:42 +00009226 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009227 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009228 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009229 ver = &tmp[0];
9230 }
9231
9232 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009233 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009234 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009235
9236 /* Add Indicator of Which Drive was Used to Boot the System */
9237 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9238 tmp[1] = ':';
9239 tmp[2] = '\0';
9240
Fred Drake4d1e64b2002-04-15 19:40:07 +00009241 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009242}
9243#endif
9244
Barry Warsaw4a342091996-12-19 23:50:02 +00009245static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009246all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009247{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009248#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009249 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009250#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009251#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009253#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009254#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009255 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009256#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009257#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009258 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009259#endif
Fred Drakec9680921999-12-13 16:37:25 +00009260#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009262#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009263#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009264 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009265#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009266#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009267 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009268#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009269#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009270 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009271#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009272#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009273 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009274#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009275#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009276 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009277#endif
9278#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009279 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009280#endif
9281#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009282 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009283#endif
9284#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009285 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009286#endif
9287#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009288 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009289#endif
9290#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009291 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009292#endif
9293#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009294 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009295#endif
9296#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009297 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009298#endif
9299#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009300 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009301#endif
9302#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009303 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009304#endif
9305#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009306 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009307#endif
9308#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009309 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009310#endif
9311#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009312 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009313#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009314#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009315 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009316#endif
9317#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009318 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009319#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009320#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009321 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009322#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009323#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009324 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009325#endif
9326#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009327 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009328#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009329
Tim Peters5aa91602002-01-30 05:46:57 +00009330/* MS Windows */
9331#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009332 /* Don't inherit in child processes. */
9333 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009334#endif
9335#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009336 /* Optimize for short life (keep in memory). */
9337 /* MS forgot to define this one with a non-underscore form too. */
9338 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009339#endif
9340#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009341 /* Automatically delete when last handle is closed. */
9342 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009343#endif
9344#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009345 /* Optimize for random access. */
9346 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009347#endif
9348#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009349 /* Optimize for sequential access. */
9350 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009351#endif
9352
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009353/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009354#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009355 /* Send a SIGIO signal whenever input or output
9356 becomes available on file descriptor */
9357 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009358#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009359#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009360 /* Direct disk access. */
9361 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009362#endif
9363#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009364 /* Must be a directory. */
9365 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009366#endif
9367#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009368 /* Do not follow links. */
9369 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009370#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009371#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009372 /* Do not update the access time. */
9373 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009374#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009375
Victor Stinnerd6f85422010-05-05 23:33:33 +00009376 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009377#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009378 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009379#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009380#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009381 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009382#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009383#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009384 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009385#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009386#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009387 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009388#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009389#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009390 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009391#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009392#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009393 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009394#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009395#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009396 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009397#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009398#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009399 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009400#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009401#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009402 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009403#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009404#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009405 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009406#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009407#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009408 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009409#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009410#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009411 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009412#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009413#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009414 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009415#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009416#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009417 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009418#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009419#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009420 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009421#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009422#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009423 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009424#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009425#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009426 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009427#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009428
Guido van Rossum246bc171999-02-01 23:54:31 +00009429#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009430#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009431 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9432 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9433 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9434 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9435 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9436 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9437 if (ins(d, "P_PM", (long)P_PM)) return -1;
9438 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9439 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9440 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9441 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9442 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9443 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9444 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9445 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9446 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9447 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9448 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9449 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9450 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009451#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009452 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9453 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9454 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9455 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9456 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009457#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009458#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009459
Guido van Rossumd48f2521997-12-05 22:19:34 +00009460#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009461 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009462#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009463 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009464}
9465
9466
Tim Peters5aa91602002-01-30 05:46:57 +00009467#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009468#define INITFUNC initnt
9469#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009470
9471#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009472#define INITFUNC initos2
9473#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009474
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009475#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009476#define INITFUNC initposix
9477#define MODNAME "posix"
9478#endif
9479
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009480PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009481INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009482{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009483 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009484
Victor Stinnerd6f85422010-05-05 23:33:33 +00009485 m = Py_InitModule3(MODNAME,
9486 posix_methods,
9487 posix__doc__);
9488 if (m == NULL)
9489 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009490
Victor Stinnerd6f85422010-05-05 23:33:33 +00009491 /* Initialize environ dictionary */
9492 v = convertenviron();
9493 Py_XINCREF(v);
9494 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9495 return;
9496 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009497
Victor Stinnerd6f85422010-05-05 23:33:33 +00009498 if (all_ins(m))
9499 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009500
Victor Stinnerd6f85422010-05-05 23:33:33 +00009501 if (setup_confname_tables(m))
9502 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009503
Victor Stinnerd6f85422010-05-05 23:33:33 +00009504 Py_INCREF(PyExc_OSError);
9505 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009506
Guido van Rossumb3d39562000-01-31 18:41:26 +00009507#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009508 if (posix_putenv_garbage == NULL)
9509 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009510#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009511
Victor Stinnerd6f85422010-05-05 23:33:33 +00009512 if (!initialized) {
9513 stat_result_desc.name = MODNAME ".stat_result";
9514 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9515 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9516 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9517 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9518 structseq_new = StatResultType.tp_new;
9519 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009520
Victor Stinnerd6f85422010-05-05 23:33:33 +00009521 statvfs_result_desc.name = MODNAME ".statvfs_result";
9522 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009523#ifdef NEED_TICKS_PER_SECOND
9524# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009525 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009526# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009527 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009528# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009529 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009530# endif
9531#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009532 }
9533 Py_INCREF((PyObject*) &StatResultType);
9534 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9535 Py_INCREF((PyObject*) &StatVFSResultType);
9536 PyModule_AddObject(m, "statvfs_result",
9537 (PyObject*) &StatVFSResultType);
9538 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009539
9540#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009541 /*
9542 * Step 2 of weak-linking support on Mac OS X.
9543 *
9544 * The code below removes functions that are not available on the
9545 * currently active platform.
9546 *
9547 * This block allow one to use a python binary that was build on
9548 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9549 * OSX 10.4.
9550 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009551#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009552 if (fstatvfs == NULL) {
9553 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9554 return;
9555 }
9556 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009557#endif /* HAVE_FSTATVFS */
9558
9559#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009560 if (statvfs == NULL) {
9561 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9562 return;
9563 }
9564 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009565#endif /* HAVE_STATVFS */
9566
9567# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009568 if (lchown == NULL) {
9569 if (PyObject_DelAttrString(m, "lchown") == -1) {
9570 return;
9571 }
9572 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009573#endif /* HAVE_LCHOWN */
9574
9575
9576#endif /* __APPLE__ */
9577
Guido van Rossumb6775db1994-08-01 11:34:53 +00009578}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009579
9580#ifdef __cplusplus
9581}
9582#endif
9583
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009584