blob: ea810ecaea8fc62c89a106c8193bf15e26a9a805 [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"
30
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000031#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000032# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#endif /* defined(__VMS) */
34
Anthony Baxterac6bd462006-04-13 02:06:09 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045#ifndef Py_USING_UNICODE
46/* This is used in signatures of functions. */
47#define Py_UNICODE void
48#endif
49
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000050#if defined(PYOS_OS2)
51#define INCL_DOS
52#define INCL_DOSERRORS
53#define INCL_DOSPROCESS
54#define INCL_NOPMAPI
55#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000056#if defined(PYCC_GCC)
57#include <ctype.h>
58#include <io.h>
59#include <stdio.h>
60#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000061#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000062#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000063#endif
64
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000065#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#endif /* HAVE_SYS_TYPES_H */
68
69#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000070#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000071#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072
Guido van Rossum36bc6801995-06-14 22:54:23 +000073#ifdef HAVE_SYS_WAIT_H
Victor Stinnerd6f85422010-05-05 23:33:33 +000074#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000076
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000077#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000078#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000080
Guido van Rossumb6775db1994-08-01 11:34:53 +000081#ifdef HAVE_FCNTL_H
82#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000083#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000084
Guido van Rossuma6535fd2001-10-18 19:44:10 +000085#ifdef HAVE_GRP_H
86#include <grp.h>
87#endif
88
Barry Warsaw5676bd12003-01-07 20:57:09 +000089#ifdef HAVE_SYSEXITS_H
90#include <sysexits.h>
91#endif /* HAVE_SYSEXITS_H */
92
Anthony Baxter8a560de2004-10-13 15:30:56 +000093#ifdef HAVE_SYS_LOADAVG_H
94#include <sys/loadavg.h>
95#endif
96
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000098/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000099#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000100#include <process.h>
101#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000102#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000103#define HAVE_GETCWD 1
104#define HAVE_OPENDIR 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000105#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000106#if defined(__OS2__)
107#define HAVE_EXECV 1
108#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000109#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#include <process.h>
111#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000112#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#define HAVE_EXECV 1
114#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_OPENDIR 1
116#define HAVE_PIPE 1
117#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000118#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_WAIT 1
120#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000121#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000122#define HAVE_GETCWD 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000123#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000124#define HAVE_EXECV 1
125#define HAVE_PIPE 1
126#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000127#define HAVE_SYSTEM 1
128#define HAVE_CWAIT 1
129#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000130#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000131#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000132#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
133/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinnerd6f85422010-05-05 23:33:33 +0000134#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135/* Unix functions that the configure script doesn't check for */
136#define HAVE_EXECV 1
137#define HAVE_FORK 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000138#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000139#define HAVE_FORK1 1
140#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#define HAVE_GETCWD 1
142#define HAVE_GETEGID 1
143#define HAVE_GETEUID 1
144#define HAVE_GETGID 1
145#define HAVE_GETPPID 1
146#define HAVE_GETUID 1
147#define HAVE_KILL 1
148#define HAVE_OPENDIR 1
149#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000150#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000153#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#define HAVE_WAIT 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000155#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000156#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#endif /* _MSC_VER */
158#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000159#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000160#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000161
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000162#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000163
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000164#if defined(__sgi)&&_COMPILER_VERSION>=700
165/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
166 (default) */
167extern char *ctermid_r(char *);
168#endif
169
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000170#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000174#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000175extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000179#endif
180#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int chdir(char *);
182extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000183#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chdir(const char *);
185extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000186#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000187#ifdef __BORLANDC__
188extern int chmod(const char *, int);
189#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000190extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000191#endif
Christian Heimes36281872007-11-30 21:11:28 +0000192/*#ifdef HAVE_FCHMOD
193extern int fchmod(int, mode_t);
194#endif*/
195/*#ifdef HAVE_LCHMOD
196extern int lchmod(const char *, mode_t);
197#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int chown(const char *, uid_t, gid_t);
199extern char *getcwd(char *, int);
200extern char *strerror(int);
201extern int link(const char *, const char *);
202extern int rename(const char *, const char *);
203extern int stat(const char *, struct stat *);
204extern int unlink(const char *);
205extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000208#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000211#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000213
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#ifdef HAVE_UTIME_H
217#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000218#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000220#ifdef HAVE_SYS_UTIME_H
221#include <sys/utime.h>
222#define HAVE_UTIME_H /* pretend we do for the rest of this file */
223#endif /* HAVE_SYS_UTIME_H */
224
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#ifdef HAVE_SYS_TIMES_H
226#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_PARAM_H
230#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
233#ifdef HAVE_SYS_UTSNAME_H
234#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000241#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000242#include <direct.h>
243#define NAMLEN(dirent) strlen((dirent)->d_name)
244#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000247#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#endif
251#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000253#endif
254#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000256#endif
257#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000259#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000260#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000262#endif
263#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000265#endif
266#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000268#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000269#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000270#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#include <windows.h>
Victor Stinnerd6f85422010-05-05 23:33:33 +0000272#include <shellapi.h> /* for ShellExecute() */
273#define popen _popen
274#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000275#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276
Guido van Rossumd48f2521997-12-05 22:19:34 +0000277#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000279#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000282#if defined(PATH_MAX) && PATH_MAX > 1024
283#define MAXPATHLEN PATH_MAX
284#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000285#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000286#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#endif /* MAXPATHLEN */
288
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000289#ifdef UNION_WAIT
290/* Emulate some macros on systems that have a union instead of macros */
291
292#ifndef WIFEXITED
293#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
294#endif
295
296#ifndef WEXITSTATUS
297#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
298#endif
299
300#ifndef WTERMSIG
301#define WTERMSIG(u_wait) ((u_wait).w_termsig)
302#endif
303
Neal Norwitzd5a37542006-03-20 06:48:34 +0000304#define WAIT_TYPE union wait
305#define WAIT_STATUS_INT(s) (s.w_status)
306
307#else /* !UNION_WAIT */
308#define WAIT_TYPE int
309#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000310#endif /* UNION_WAIT */
311
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000312/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000313#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000314#define PARSE_PID "i"
315#define PyLong_FromPid PyInt_FromLong
316#define PyLong_AsPid PyInt_AsLong
317#elif SIZEOF_PID_T == SIZEOF_LONG
318#define PARSE_PID "l"
319#define PyLong_FromPid PyInt_FromLong
320#define PyLong_AsPid PyInt_AsLong
321#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
322#define PARSE_PID "L"
323#define PyLong_FromPid PyLong_FromLongLong
324#define PyLong_AsPid PyInt_AsLongLong
325#else
326#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000327#endif /* SIZEOF_PID_T */
328
Greg Wardb48bc172000-03-01 21:51:56 +0000329/* Don't use the "_r" form if we don't need it (also, won't have a
330 prototype for it, at least on Solaris -- maybe others as well?). */
331#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
332#define USE_CTERMID_R
333#endif
334
335#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
336#define USE_TMPNAM_R
337#endif
338
Tim Peters11b23062003-04-23 02:39:17 +0000339#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000340#include <sys/mkdev.h>
341#else
342#if defined(MAJOR_IN_SYSMACROS)
343#include <sys/sysmacros.h>
344#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000345#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
346#include <sys/mkdev.h>
347#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000348#endif
Fred Drake699f3522000-06-29 21:12:41 +0000349
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000350#if defined _MSC_VER && _MSC_VER >= 1400
351/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
352 * valid and throw an assertion if it isn't.
353 * Normally, an invalid fd is likely to be a C program error and therefore
354 * an assertion can be useful, but it does contradict the POSIX standard
355 * which for write(2) states:
356 * "Otherwise, -1 shall be returned and errno set to indicate the error."
357 * "[EBADF] The fildes argument is not a valid file descriptor open for
358 * writing."
359 * Furthermore, python allows the user to enter any old integer
360 * as a fd and should merely raise a python exception on error.
361 * The Microsoft CRT doesn't provide an official way to check for the
362 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000363 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000364 * internal structures involved.
365 * The structures below must be updated for each version of visual studio
366 * according to the file internal.h in the CRT source, until MS comes
367 * up with a less hacky way to do this.
368 * (all of this is to avoid globally modifying the CRT behaviour using
369 * _set_invalid_parameter_handler() and _CrtSetReportMode())
370 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000371/* The actual size of the structure is determined at runtime.
372 * Only the first items must be present.
373 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000374typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000375 intptr_t osfhnd;
376 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000377} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000378
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000379extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000380#define IOINFO_L2E 5
381#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
382#define IOINFO_ARRAYS 64
383#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
384#define FOPEN 0x01
385#define _NO_CONSOLE_FILENO (intptr_t)-2
386
387/* This function emulates what the windows CRT does to validate file handles */
388int
389_PyVerify_fd(int fd)
390{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000391 const int i1 = fd >> IOINFO_L2E;
392 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000393
Victor Stinnerd6f85422010-05-05 23:33:33 +0000394 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000395
Victor Stinnerd6f85422010-05-05 23:33:33 +0000396 /* Determine the actual size of the ioinfo structure,
397 * as used by the CRT loaded in memory
398 */
399 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
400 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
401 }
402 if (sizeof_ioinfo == 0) {
403 /* This should not happen... */
404 goto fail;
405 }
406
407 /* See that it isn't a special CLEAR fileno */
408 if (fd != _NO_CONSOLE_FILENO) {
409 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
410 * we check pointer validity and other info
411 */
412 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
413 /* finally, check that the file is open */
414 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
415 if (info->osfile & FOPEN) {
416 return 1;
417 }
418 }
419 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000420 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000421 errno = EBADF;
422 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000423}
424
425/* the special case of checking dup2. The target fd must be in a sensible range */
426static int
427_PyVerify_fd_dup2(int fd1, int fd2)
428{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000429 if (!_PyVerify_fd(fd1))
430 return 0;
431 if (fd2 == _NO_CONSOLE_FILENO)
432 return 0;
433 if ((unsigned)fd2 < _NHANDLE_)
434 return 1;
435 else
436 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000437}
438#else
439/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
440#define _PyVerify_fd_dup2(A, B) (1)
441#endif
442
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000444#ifdef WITH_NEXT_FRAMEWORK
445/* On Darwin/MacOSX a shared library or framework has no access to
446** environ directly, we must obtain it with _NSGetEnviron().
447*/
448#include <crt_externs.h>
449static char **environ;
450#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000451extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000452#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453
Barry Warsaw53699e91996-12-10 23:23:01 +0000454static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000455convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000457 PyObject *d;
458 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000459#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000460 APIRET rc;
461 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
462#endif
463 d = PyDict_New();
464 if (d == NULL)
465 return NULL;
466#ifdef WITH_NEXT_FRAMEWORK
467 if (environ == NULL)
468 environ = *_NSGetEnviron();
469#endif
470 if (environ == NULL)
471 return d;
472 /* This part ignores errors */
473 for (e = environ; *e != NULL; e++) {
474 PyObject *k;
475 PyObject *v;
476 char *p = strchr(*e, '=');
477 if (p == NULL)
478 continue;
479 k = PyString_FromStringAndSize(*e, (int)(p-*e));
480 if (k == NULL) {
481 PyErr_Clear();
482 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000483 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000484 v = PyString_FromString(p+1);
485 if (v == NULL) {
486 PyErr_Clear();
487 Py_DECREF(k);
488 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000489 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000490 if (PyDict_GetItem(d, k) == NULL) {
491 if (PyDict_SetItem(d, k, v) != 0)
492 PyErr_Clear();
493 }
494 Py_DECREF(k);
495 Py_DECREF(v);
496 }
497#if defined(PYOS_OS2)
498 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
499 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
500 PyObject *v = PyString_FromString(buffer);
501 PyDict_SetItemString(d, "BEGINLIBPATH", v);
502 Py_DECREF(v);
503 }
504 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
505 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
506 PyObject *v = PyString_FromString(buffer);
507 PyDict_SetItemString(d, "ENDLIBPATH", v);
508 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000509 }
510#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000511 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000512}
513
514
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515/* Set a POSIX-specific error from errno, and return NULL */
516
Barry Warsawd58d7641998-07-23 16:14:40 +0000517static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000518posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000519{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000520 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000521}
Barry Warsawd58d7641998-07-23 16:14:40 +0000522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000523posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000524{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000525 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000526}
527
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000528#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000529static PyObject *
530posix_error_with_unicode_filename(Py_UNICODE* name)
531{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000532 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000533}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000534#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000535
536
Mark Hammondef8b6542001-05-13 08:04:26 +0000537static PyObject *
538posix_error_with_allocated_filename(char* name)
539{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000540 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
541 PyMem_Free(name);
542 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000543}
544
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000545#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000546static PyObject *
547win32_error(char* function, char* filename)
548{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000549 /* XXX We should pass the function name along in the future.
550 (_winreg.c also wants to pass the function name.)
551 This would however require an additional param to the
552 Windows error object, which is non-trivial.
553 */
554 errno = GetLastError();
555 if (filename)
556 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
557 else
558 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000559}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000561static PyObject *
562win32_error_unicode(char* function, Py_UNICODE* filename)
563{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000564 /* XXX - see win32_error for comments on 'function' */
565 errno = GetLastError();
566 if (filename)
567 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
568 else
569 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000570}
571
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000572static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000573convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000574{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000575 if (PyUnicode_CheckExact(*param))
576 Py_INCREF(*param);
577 else if (PyUnicode_Check(*param))
578 /* For a Unicode subtype that's not a Unicode object,
579 return a true Unicode object with the same data. */
580 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
581 PyUnicode_GET_SIZE(*param));
582 else
583 *param = PyUnicode_FromEncodedObject(*param,
584 Py_FileSystemDefaultEncoding,
585 "strict");
586 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000587}
588
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000589#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000590
Guido van Rossumd48f2521997-12-05 22:19:34 +0000591#if defined(PYOS_OS2)
592/**********************************************************************
593 * Helper Function to Trim and Format OS/2 Messages
594 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000595static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000596os2_formatmsg(char *msgbuf, int msglen, char *reason)
597{
598 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
599
600 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000601 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000602
Victor Stinner862490a2010-05-06 00:03:44 +0000603 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
604 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000605 }
606
607 /* Add Optional Reason Text */
608 if (reason) {
609 strcat(msgbuf, " : ");
610 strcat(msgbuf, reason);
611 }
612}
613
614/**********************************************************************
615 * Decode an OS/2 Operating System Error Code
616 *
617 * A convenience function to lookup an OS/2 error code and return a
618 * text message we can use to raise a Python exception.
619 *
620 * Notes:
621 * The messages for errors returned from the OS/2 kernel reside in
622 * the file OSO001.MSG in the \OS2 directory hierarchy.
623 *
624 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000625static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000626os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
627{
628 APIRET rc;
629 ULONG msglen;
630
631 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
632 Py_BEGIN_ALLOW_THREADS
633 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
634 errorcode, "oso001.msg", &msglen);
635 Py_END_ALLOW_THREADS
636
637 if (rc == NO_ERROR)
638 os2_formatmsg(msgbuf, msglen, reason);
639 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000640 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000641 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000642
643 return msgbuf;
644}
645
646/* Set an OS/2-specific error and return NULL. OS/2 kernel
647 errors are not in a global variable e.g. 'errno' nor are
648 they congruent with posix error numbers. */
649
Victor Stinnerd6f85422010-05-05 23:33:33 +0000650static PyObject *
651os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000652{
653 char text[1024];
654 PyObject *v;
655
656 os2_strerror(text, sizeof(text), code, "");
657
658 v = Py_BuildValue("(is)", code, text);
659 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000660 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000661 Py_DECREF(v);
662 }
663 return NULL; /* Signal to Python that an Exception is Pending */
664}
665
666#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667
668/* POSIX generic methods */
669
Barry Warsaw53699e91996-12-10 23:23:01 +0000670static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000671posix_fildes(PyObject *fdobj, int (*func)(int))
672{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000673 int fd;
674 int res;
675 fd = PyObject_AsFileDescriptor(fdobj);
676 if (fd < 0)
677 return NULL;
678 if (!_PyVerify_fd(fd))
679 return posix_error();
680 Py_BEGIN_ALLOW_THREADS
681 res = (*func)(fd);
682 Py_END_ALLOW_THREADS
683 if (res < 0)
684 return posix_error();
685 Py_INCREF(Py_None);
686 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000687}
Guido van Rossum21142a01999-01-08 21:05:37 +0000688
689static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000690posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000692 char *path1 = NULL;
693 int res;
694 if (!PyArg_ParseTuple(args, format,
695 Py_FileSystemDefaultEncoding, &path1))
696 return NULL;
697 Py_BEGIN_ALLOW_THREADS
698 res = (*func)(path1);
699 Py_END_ALLOW_THREADS
700 if (res < 0)
701 return posix_error_with_allocated_filename(path1);
702 PyMem_Free(path1);
703 Py_INCREF(Py_None);
704 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705}
706
Barry Warsaw53699e91996-12-10 23:23:01 +0000707static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000708posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000709 char *format,
710 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000711{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000712 char *path1 = NULL, *path2 = NULL;
713 int res;
714 if (!PyArg_ParseTuple(args, format,
715 Py_FileSystemDefaultEncoding, &path1,
716 Py_FileSystemDefaultEncoding, &path2))
717 return NULL;
718 Py_BEGIN_ALLOW_THREADS
719 res = (*func)(path1, path2);
720 Py_END_ALLOW_THREADS
721 PyMem_Free(path1);
722 PyMem_Free(path2);
723 if (res != 0)
724 /* XXX how to report both path1 and path2??? */
725 return posix_error();
726 Py_INCREF(Py_None);
727 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000728}
729
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000730#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000731static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000732win32_1str(PyObject* args, char* func,
733 char* format, BOOL (__stdcall *funcA)(LPCSTR),
734 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000735{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000736 PyObject *uni;
737 char *ansi;
738 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000739
Victor Stinnerd6f85422010-05-05 23:33:33 +0000740 if (!PyArg_ParseTuple(args, wformat, &uni))
741 PyErr_Clear();
742 else {
743 Py_BEGIN_ALLOW_THREADS
744 result = funcW(PyUnicode_AsUnicode(uni));
745 Py_END_ALLOW_THREADS
746 if (!result)
747 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
748 Py_INCREF(Py_None);
749 return Py_None;
750 }
751 if (!PyArg_ParseTuple(args, format, &ansi))
752 return NULL;
753 Py_BEGIN_ALLOW_THREADS
754 result = funcA(ansi);
755 Py_END_ALLOW_THREADS
756 if (!result)
757 return win32_error(func, ansi);
758 Py_INCREF(Py_None);
759 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000760
761}
762
763/* This is a reimplementation of the C library's chdir function,
764 but one that produces Win32 errors instead of DOS error codes.
765 chdir is essentially a wrapper around SetCurrentDirectory; however,
766 it also needs to set "magic" environment variables indicating
767 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000768static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000769win32_chdir(LPCSTR path)
770{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000771 char new_path[MAX_PATH+1];
772 int result;
773 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000774
Victor Stinnerd6f85422010-05-05 23:33:33 +0000775 if(!SetCurrentDirectoryA(path))
776 return FALSE;
777 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
778 if (!result)
779 return FALSE;
780 /* In the ANSI API, there should not be any paths longer
781 than MAX_PATH. */
782 assert(result <= MAX_PATH+1);
783 if (strncmp(new_path, "\\\\", 2) == 0 ||
784 strncmp(new_path, "//", 2) == 0)
785 /* UNC path, nothing to do. */
786 return TRUE;
787 env[1] = new_path[0];
788 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000789}
790
791/* The Unicode version differs from the ANSI version
792 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000793static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000794win32_wchdir(LPCWSTR path)
795{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000796 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
797 int result;
798 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000799
Victor Stinnerd6f85422010-05-05 23:33:33 +0000800 if(!SetCurrentDirectoryW(path))
801 return FALSE;
802 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
803 if (!result)
804 return FALSE;
805 if (result > MAX_PATH+1) {
806 new_path = malloc(result * sizeof(wchar_t));
807 if (!new_path) {
808 SetLastError(ERROR_OUTOFMEMORY);
809 return FALSE;
810 }
811 result = GetCurrentDirectoryW(result, new_path);
812 if (!result) {
813 free(new_path);
814 return FALSE;
815 }
816 }
817 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
818 wcsncmp(new_path, L"//", 2) == 0)
819 /* UNC path, nothing to do. */
820 return TRUE;
821 env[1] = new_path[0];
822 result = SetEnvironmentVariableW(env, new_path);
823 if (new_path != _new_path)
824 free(new_path);
825 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000826}
827#endif
828
Antoine Pitrouff48c0a2011-07-01 22:56:03 +0200829/* choose the appropriate stat and fstat functions and return structs */
830#undef STAT
831#undef FSTAT
832#undef STRUCT_STAT
833#if defined(MS_WIN64) || defined(MS_WINDOWS)
834# define STAT win32_stat
835# define FSTAT win32_fstat
836# define STRUCT_STAT struct win32_stat
837#else
838# define STAT stat
839# define FSTAT fstat
840# define STRUCT_STAT struct stat
841#endif
842
Martin v. Löwis14694662006-02-03 12:54:16 +0000843#ifdef MS_WINDOWS
844/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
845 - time stamps are restricted to second resolution
846 - file modification times suffer from forth-and-back conversions between
847 UTC and local time
848 Therefore, we implement our own stat, based on the Win32 API directly.
849*/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000850#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000851
852struct win32_stat{
853 int st_dev;
854 __int64 st_ino;
855 unsigned short st_mode;
856 int st_nlink;
857 int st_uid;
858 int st_gid;
859 int st_rdev;
860 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000861 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000862 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000863 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000864 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000865 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000866 int st_ctime_nsec;
867};
868
869static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
870
871static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000872FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000873{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000874 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
875 /* Cannot simply cast and dereference in_ptr,
876 since it might not be aligned properly */
877 __int64 in;
878 memcpy(&in, in_ptr, sizeof(in));
879 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000880 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000881}
882
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000883static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000884time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000885{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000886 /* XXX endianness */
887 __int64 out;
888 out = time_in + secs_between_epochs;
889 out = out * 10000000 + nsec_in / 100;
890 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000891}
892
Martin v. Löwis14694662006-02-03 12:54:16 +0000893/* Below, we *know* that ugo+r is 0444 */
894#if _S_IREAD != 0400
895#error Unsupported C library
896#endif
897static int
898attributes_to_mode(DWORD attr)
899{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000900 int m = 0;
901 if (attr & FILE_ATTRIBUTE_DIRECTORY)
902 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
903 else
904 m |= _S_IFREG;
905 if (attr & FILE_ATTRIBUTE_READONLY)
906 m |= 0444;
907 else
908 m |= 0666;
909 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000910}
911
912static int
913attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
914{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000915 memset(result, 0, sizeof(*result));
916 result->st_mode = attributes_to_mode(info->dwFileAttributes);
917 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
918 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
919 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
920 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000921
Victor Stinnerd6f85422010-05-05 23:33:33 +0000922 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000923}
924
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000925static BOOL
926attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
927{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000928 HANDLE hFindFile;
929 WIN32_FIND_DATAA FileData;
930 hFindFile = FindFirstFileA(pszFile, &FileData);
931 if (hFindFile == INVALID_HANDLE_VALUE)
932 return FALSE;
933 FindClose(hFindFile);
934 pfad->dwFileAttributes = FileData.dwFileAttributes;
935 pfad->ftCreationTime = FileData.ftCreationTime;
936 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
937 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
938 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
939 pfad->nFileSizeLow = FileData.nFileSizeLow;
940 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000941}
942
943static BOOL
944attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
945{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000946 HANDLE hFindFile;
947 WIN32_FIND_DATAW FileData;
948 hFindFile = FindFirstFileW(pszFile, &FileData);
949 if (hFindFile == INVALID_HANDLE_VALUE)
950 return FALSE;
951 FindClose(hFindFile);
952 pfad->dwFileAttributes = FileData.dwFileAttributes;
953 pfad->ftCreationTime = FileData.ftCreationTime;
954 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
955 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
956 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
957 pfad->nFileSizeLow = FileData.nFileSizeLow;
958 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000959}
960
Victor Stinnerd6f85422010-05-05 23:33:33 +0000961static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000962win32_stat(const char* path, struct win32_stat *result)
963{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000964 WIN32_FILE_ATTRIBUTE_DATA info;
965 int code;
966 char *dot;
967 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
968 if (GetLastError() != ERROR_SHARING_VIOLATION) {
969 /* Protocol violation: we explicitly clear errno, instead of
970 setting it to a POSIX error. Callers should use GetLastError. */
971 errno = 0;
972 return -1;
973 } else {
974 /* Could not get attributes on open file. Fall back to
975 reading the directory. */
976 if (!attributes_from_dir(path, &info)) {
977 /* Very strange. This should not fail now */
978 errno = 0;
979 return -1;
980 }
981 }
982 }
983 code = attribute_data_to_stat(&info, result);
984 if (code != 0)
985 return code;
986 /* Set S_IFEXEC if it is an .exe, .bat, ... */
987 dot = strrchr(path, '.');
988 if (dot) {
989 if (stricmp(dot, ".bat") == 0 ||
990 stricmp(dot, ".cmd") == 0 ||
991 stricmp(dot, ".exe") == 0 ||
992 stricmp(dot, ".com") == 0)
993 result->st_mode |= 0111;
994 }
995 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +0000996}
997
Victor Stinnerd6f85422010-05-05 23:33:33 +0000998static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000999win32_wstat(const wchar_t* path, struct win32_stat *result)
1000{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001001 int code;
1002 const wchar_t *dot;
1003 WIN32_FILE_ATTRIBUTE_DATA info;
1004 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1005 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1006 /* Protocol violation: we explicitly clear errno, instead of
1007 setting it to a POSIX error. Callers should use GetLastError. */
1008 errno = 0;
1009 return -1;
1010 } else {
1011 /* Could not get attributes on open file. Fall back to
1012 reading the directory. */
1013 if (!attributes_from_dir_w(path, &info)) {
1014 /* Very strange. This should not fail now */
1015 errno = 0;
1016 return -1;
1017 }
1018 }
1019 }
1020 code = attribute_data_to_stat(&info, result);
1021 if (code < 0)
1022 return code;
1023 /* Set IFEXEC if it is an .exe, .bat, ... */
1024 dot = wcsrchr(path, '.');
1025 if (dot) {
1026 if (_wcsicmp(dot, L".bat") == 0 ||
1027 _wcsicmp(dot, L".cmd") == 0 ||
1028 _wcsicmp(dot, L".exe") == 0 ||
1029 _wcsicmp(dot, L".com") == 0)
1030 result->st_mode |= 0111;
1031 }
1032 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001033}
1034
1035static int
1036win32_fstat(int file_number, struct win32_stat *result)
1037{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001038 BY_HANDLE_FILE_INFORMATION info;
1039 HANDLE h;
1040 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001041
Victor Stinnerd6f85422010-05-05 23:33:33 +00001042 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001043
Victor Stinnerd6f85422010-05-05 23:33:33 +00001044 /* Protocol violation: we explicitly clear errno, instead of
1045 setting it to a POSIX error. Callers should use GetLastError. */
1046 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001047
Victor Stinnerd6f85422010-05-05 23:33:33 +00001048 if (h == INVALID_HANDLE_VALUE) {
1049 /* This is really a C library error (invalid file handle).
1050 We set the Win32 error to the closes one matching. */
1051 SetLastError(ERROR_INVALID_HANDLE);
1052 return -1;
1053 }
1054 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001055
Victor Stinnerd6f85422010-05-05 23:33:33 +00001056 type = GetFileType(h);
1057 if (type == FILE_TYPE_UNKNOWN) {
1058 DWORD error = GetLastError();
1059 if (error != 0) {
1060 return -1;
1061 }
1062 /* else: valid but unknown file */
1063 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001064
Victor Stinnerd6f85422010-05-05 23:33:33 +00001065 if (type != FILE_TYPE_DISK) {
1066 if (type == FILE_TYPE_CHAR)
1067 result->st_mode = _S_IFCHR;
1068 else if (type == FILE_TYPE_PIPE)
1069 result->st_mode = _S_IFIFO;
1070 return 0;
1071 }
1072
1073 if (!GetFileInformationByHandle(h, &info)) {
1074 return -1;
1075 }
1076
1077 /* similar to stat() */
1078 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1079 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1080 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1081 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1082 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1083 /* specific to fstat() */
1084 result->st_nlink = info.nNumberOfLinks;
1085 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1086 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001087}
1088
1089#endif /* MS_WINDOWS */
1090
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001091PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001092"stat_result: Result from stat or lstat.\n\n\
1093This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001094 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001095or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1096\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001097Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1098or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001099\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001100See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001101
1102static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001103 {"st_mode", "protection bits"},
1104 {"st_ino", "inode"},
1105 {"st_dev", "device"},
1106 {"st_nlink", "number of hard links"},
1107 {"st_uid", "user ID of owner"},
1108 {"st_gid", "group ID of owner"},
1109 {"st_size", "total size, in bytes"},
1110 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1111 {NULL, "integer time of last access"},
1112 {NULL, "integer time of last modification"},
1113 {NULL, "integer time of last change"},
1114 {"st_atime", "time of last access"},
1115 {"st_mtime", "time of last modification"},
1116 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001117#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001118 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001120#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001121 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001123#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001124 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001125#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001126#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001127 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001128#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001129#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001130 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001131#endif
1132#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001133 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001134#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001135 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001136};
1137
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001138#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001139#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001141#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001142#endif
1143
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001144#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001145#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1146#else
1147#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1148#endif
1149
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001150#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001151#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1152#else
1153#define ST_RDEV_IDX ST_BLOCKS_IDX
1154#endif
1155
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001156#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1157#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1158#else
1159#define ST_FLAGS_IDX ST_RDEV_IDX
1160#endif
1161
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001162#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001163#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001164#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001165#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001166#endif
1167
1168#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1169#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1170#else
1171#define ST_BIRTHTIME_IDX ST_GEN_IDX
1172#endif
1173
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001174static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001175 "stat_result", /* name */
1176 stat_result__doc__, /* doc */
1177 stat_result_fields,
1178 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001179};
1180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001181PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1183This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001184 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001185or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001186\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001187See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001188
1189static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001190 {"f_bsize", },
1191 {"f_frsize", },
1192 {"f_blocks", },
1193 {"f_bfree", },
1194 {"f_bavail", },
1195 {"f_files", },
1196 {"f_ffree", },
1197 {"f_favail", },
1198 {"f_flag", },
1199 {"f_namemax",},
1200 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001201};
1202
1203static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001204 "statvfs_result", /* name */
1205 statvfs_result__doc__, /* doc */
1206 statvfs_result_fields,
1207 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001208};
1209
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001210static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001211static PyTypeObject StatResultType;
1212static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001213static newfunc structseq_new;
1214
1215static PyObject *
1216statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1217{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001218 PyStructSequence *result;
1219 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001220
Victor Stinnerd6f85422010-05-05 23:33:33 +00001221 result = (PyStructSequence*)structseq_new(type, args, kwds);
1222 if (!result)
1223 return NULL;
1224 /* If we have been initialized from a tuple,
1225 st_?time might be set to None. Initialize it
1226 from the int slots. */
1227 for (i = 7; i <= 9; i++) {
1228 if (result->ob_item[i+3] == Py_None) {
1229 Py_DECREF(Py_None);
1230 Py_INCREF(result->ob_item[i]);
1231 result->ob_item[i+3] = result->ob_item[i];
1232 }
1233 }
1234 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001235}
1236
1237
1238
1239/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001240static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001241
1242PyDoc_STRVAR(stat_float_times__doc__,
1243"stat_float_times([newval]) -> oldval\n\n\
1244Determine whether os.[lf]stat represents time stamps as float objects.\n\
1245If newval is True, future calls to stat() return floats, if it is False,\n\
1246future calls return ints. \n\
1247If newval is omitted, return the current setting.\n");
1248
1249static PyObject*
1250stat_float_times(PyObject* self, PyObject *args)
1251{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001252 int newval = -1;
1253 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1254 return NULL;
1255 if (newval == -1)
1256 /* Return old value */
1257 return PyBool_FromLong(_stat_float_times);
1258 _stat_float_times = newval;
1259 Py_INCREF(Py_None);
1260 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001261}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001263static void
1264fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1265{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001266 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001267#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001268 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001269#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001270 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001271#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001272 if (!ival)
1273 return;
1274 if (_stat_float_times) {
1275 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1276 } else {
1277 fval = ival;
1278 Py_INCREF(fval);
1279 }
1280 PyStructSequence_SET_ITEM(v, index, ival);
1281 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001282}
1283
Tim Peters5aa91602002-01-30 05:46:57 +00001284/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001285 (used by posix_stat() and posix_fstat()) */
1286static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001287_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001289 unsigned long ansec, mnsec, cnsec;
1290 PyObject *v = PyStructSequence_New(&StatResultType);
1291 if (v == NULL)
1292 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001293
Victor Stinnerd6f85422010-05-05 23:33:33 +00001294 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001295#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001296 PyStructSequence_SET_ITEM(v, 1,
1297 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001298#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001299 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001300#endif
1301#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001302 PyStructSequence_SET_ITEM(v, 2,
1303 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001304#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001305 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001306#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1308 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1309 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001310#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001311 PyStructSequence_SET_ITEM(v, 6,
1312 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001313#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001314 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001315#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001316
Martin v. Löwis14694662006-02-03 12:54:16 +00001317#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001318 ansec = st->st_atim.tv_nsec;
1319 mnsec = st->st_mtim.tv_nsec;
1320 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001321#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001322 ansec = st->st_atimespec.tv_nsec;
1323 mnsec = st->st_mtimespec.tv_nsec;
1324 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001325#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001326 ansec = st->st_atime_nsec;
1327 mnsec = st->st_mtime_nsec;
1328 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001329#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001330 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001332 fill_time(v, 7, st->st_atime, ansec);
1333 fill_time(v, 8, st->st_mtime, mnsec);
1334 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001335
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001336#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001337 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1338 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001340#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001341 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1342 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001344#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001345 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1346 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001347#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001348#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001349 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1350 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001351#endif
1352#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001353 {
1354 PyObject *val;
1355 unsigned long bsec,bnsec;
1356 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001357#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001358 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001360 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001361#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001362 if (_stat_float_times) {
1363 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1364 } else {
1365 val = PyInt_FromLong((long)bsec);
1366 }
1367 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1368 val);
1369 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001370#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001371#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001372 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1373 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001374#endif
Fred Drake699f3522000-06-29 21:12:41 +00001375
Victor Stinnerd6f85422010-05-05 23:33:33 +00001376 if (PyErr_Occurred()) {
1377 Py_DECREF(v);
1378 return NULL;
1379 }
Fred Drake699f3522000-06-29 21:12:41 +00001380
Victor Stinnerd6f85422010-05-05 23:33:33 +00001381 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001382}
1383
Martin v. Löwisd8948722004-06-02 09:57:56 +00001384#ifdef MS_WINDOWS
1385
1386/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1387 where / can be used in place of \ and the trailing slash is optional.
1388 Both SERVER and SHARE must have at least one character.
1389*/
1390
1391#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1392#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001393#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001394#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001395#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001396
Tim Peters4ad82172004-08-30 17:02:04 +00001397static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001398IsUNCRootA(char *path, int pathlen)
1399{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001400 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001401
Victor Stinnerd6f85422010-05-05 23:33:33 +00001402 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001403
Victor Stinnerd6f85422010-05-05 23:33:33 +00001404 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1405 /* minimum UNCRoot is \\x\y */
1406 return FALSE;
1407 for (i = 2; i < pathlen ; i++)
1408 if (ISSLASH(path[i])) break;
1409 if (i == 2 || i == pathlen)
1410 /* do not allow \\\SHARE or \\SERVER */
1411 return FALSE;
1412 share = i+1;
1413 for (i = share; i < pathlen; i++)
1414 if (ISSLASH(path[i])) break;
1415 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001416
Victor Stinnerd6f85422010-05-05 23:33:33 +00001417 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001418}
1419
Tim Peters4ad82172004-08-30 17:02:04 +00001420static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001421IsUNCRootW(Py_UNICODE *path, int pathlen)
1422{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001423 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001424
Victor Stinnerd6f85422010-05-05 23:33:33 +00001425 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001426
Victor Stinnerd6f85422010-05-05 23:33:33 +00001427 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1428 /* minimum UNCRoot is \\x\y */
1429 return FALSE;
1430 for (i = 2; i < pathlen ; i++)
1431 if (ISSLASH(path[i])) break;
1432 if (i == 2 || i == pathlen)
1433 /* do not allow \\\SHARE or \\SERVER */
1434 return FALSE;
1435 share = i+1;
1436 for (i = share; i < pathlen; i++)
1437 if (ISSLASH(path[i])) break;
1438 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001439
Victor Stinnerd6f85422010-05-05 23:33:33 +00001440 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001441}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001442#endif /* MS_WINDOWS */
1443
Barry Warsaw53699e91996-12-10 23:23:01 +00001444static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001445posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001446 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001447#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001448 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001449#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001450 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001451#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001452 char *wformat,
1453 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001454{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001455 STRUCT_STAT st;
1456 char *path = NULL; /* pass this to stat; do not free() it */
1457 char *pathfree = NULL; /* this memory must be free'd */
1458 int res;
1459 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001461#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001462 PyUnicodeObject *po;
1463 if (PyArg_ParseTuple(args, wformat, &po)) {
1464 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001465
Victor Stinnerd6f85422010-05-05 23:33:33 +00001466 Py_BEGIN_ALLOW_THREADS
1467 /* PyUnicode_AS_UNICODE result OK without
1468 thread lock as it is a simple dereference. */
1469 res = wstatfunc(wpath, &st);
1470 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001471
Victor Stinnerd6f85422010-05-05 23:33:33 +00001472 if (res != 0)
1473 return win32_error_unicode("stat", wpath);
1474 return _pystat_fromstructstat(&st);
1475 }
1476 /* Drop the argument parsing error as narrow strings
1477 are also valid. */
1478 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479#endif
1480
Victor Stinnerd6f85422010-05-05 23:33:33 +00001481 if (!PyArg_ParseTuple(args, format,
1482 Py_FileSystemDefaultEncoding, &path))
1483 return NULL;
1484 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001485
Victor Stinnerd6f85422010-05-05 23:33:33 +00001486 Py_BEGIN_ALLOW_THREADS
1487 res = (*statfunc)(path, &st);
1488 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001489
Victor Stinnerd6f85422010-05-05 23:33:33 +00001490 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001491#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001492 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001493#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001494 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001495#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001496 }
1497 else
1498 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001499
Victor Stinnerd6f85422010-05-05 23:33:33 +00001500 PyMem_Free(pathfree);
1501 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502}
1503
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001504/* POSIX methods */
1505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001507"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001508Use the real uid/gid to test for access to a path. Note that most\n\
1509operations will use the effective uid/gid, therefore this routine can\n\
1510be used in a suid/sgid environment to test if the invoking user has the\n\
1511specified access to the path. The mode argument can be F_OK to test\n\
1512existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001513
1514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001515posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001516{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001517 char *path;
1518 int mode;
1519
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001520#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001521 DWORD attr;
1522 PyUnicodeObject *po;
1523 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1524 Py_BEGIN_ALLOW_THREADS
1525 /* PyUnicode_AS_UNICODE OK without thread lock as
1526 it is a simple dereference. */
1527 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1528 Py_END_ALLOW_THREADS
1529 goto finish;
1530 }
1531 /* Drop the argument parsing error as narrow strings
1532 are also valid. */
1533 PyErr_Clear();
1534 if (!PyArg_ParseTuple(args, "eti:access",
1535 Py_FileSystemDefaultEncoding, &path, &mode))
1536 return NULL;
1537 Py_BEGIN_ALLOW_THREADS
1538 attr = GetFileAttributesA(path);
1539 Py_END_ALLOW_THREADS
1540 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001541finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001542 if (attr == 0xFFFFFFFF)
1543 /* File does not exist, or cannot read attributes */
1544 return PyBool_FromLong(0);
1545 /* Access is possible if either write access wasn't requested, or
1546 the file isn't read-only, or if it's a directory, as there are
1547 no read-only directories on Windows. */
1548 return PyBool_FromLong(!(mode & 2)
1549 || !(attr & FILE_ATTRIBUTE_READONLY)
1550 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001551#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001552 int res;
1553 if (!PyArg_ParseTuple(args, "eti:access",
1554 Py_FileSystemDefaultEncoding, &path, &mode))
1555 return NULL;
1556 Py_BEGIN_ALLOW_THREADS
1557 res = access(path, mode);
1558 Py_END_ALLOW_THREADS
1559 PyMem_Free(path);
1560 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001561#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001562}
1563
Guido van Rossumd371ff11999-01-25 16:12:23 +00001564#ifndef F_OK
1565#define F_OK 0
1566#endif
1567#ifndef R_OK
1568#define R_OK 4
1569#endif
1570#ifndef W_OK
1571#define W_OK 2
1572#endif
1573#ifndef X_OK
1574#define X_OK 1
1575#endif
1576
1577#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001578PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001579"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001580Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581
1582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001583posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001584{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001585 int id;
1586 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001587
Victor Stinnerd6f85422010-05-05 23:33:33 +00001588 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1589 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001590
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001591#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001592 /* file descriptor 0 only, the default input device (stdin) */
1593 if (id == 0) {
1594 ret = ttyname();
1595 }
1596 else {
1597 ret = NULL;
1598 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001599#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001600 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001601#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001602 if (ret == NULL)
1603 return posix_error();
1604 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001605}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001606#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001607
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001608#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001609PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001610"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001611Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001612
1613static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001614posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001615{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001616 char *ret;
1617 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001618
Greg Wardb48bc172000-03-01 21:51:56 +00001619#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001620 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001622 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001623#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001624 if (ret == NULL)
1625 return posix_error();
1626 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001627}
1628#endif
1629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001631"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001633
Barry Warsaw53699e91996-12-10 23:23:01 +00001634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001635posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001636{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001637#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001638 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001639#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001640 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001641#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001643#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001644 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001645#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001646}
1647
Fred Drake4d1e64b2002-04-15 19:40:07 +00001648#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001649PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001650"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001651Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001653
1654static PyObject *
1655posix_fchdir(PyObject *self, PyObject *fdobj)
1656{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001657 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001658}
1659#endif /* HAVE_FCHDIR */
1660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001662PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001663"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001664Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001665
Barry Warsaw53699e91996-12-10 23:23:01 +00001666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001667posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001669 char *path = NULL;
1670 int i;
1671 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001672#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001673 DWORD attr;
1674 PyUnicodeObject *po;
1675 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1676 Py_BEGIN_ALLOW_THREADS
1677 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1678 if (attr != 0xFFFFFFFF) {
1679 if (i & _S_IWRITE)
1680 attr &= ~FILE_ATTRIBUTE_READONLY;
1681 else
1682 attr |= FILE_ATTRIBUTE_READONLY;
1683 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1684 }
1685 else
1686 res = 0;
1687 Py_END_ALLOW_THREADS
1688 if (!res)
1689 return win32_error_unicode("chmod",
1690 PyUnicode_AS_UNICODE(po));
1691 Py_INCREF(Py_None);
1692 return Py_None;
1693 }
1694 /* Drop the argument parsing error as narrow strings
1695 are also valid. */
1696 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001697
Victor Stinnerd6f85422010-05-05 23:33:33 +00001698 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1699 &path, &i))
1700 return NULL;
1701 Py_BEGIN_ALLOW_THREADS
1702 attr = GetFileAttributesA(path);
1703 if (attr != 0xFFFFFFFF) {
1704 if (i & _S_IWRITE)
1705 attr &= ~FILE_ATTRIBUTE_READONLY;
1706 else
1707 attr |= FILE_ATTRIBUTE_READONLY;
1708 res = SetFileAttributesA(path, attr);
1709 }
1710 else
1711 res = 0;
1712 Py_END_ALLOW_THREADS
1713 if (!res) {
1714 win32_error("chmod", path);
1715 PyMem_Free(path);
1716 return NULL;
1717 }
1718 PyMem_Free(path);
1719 Py_INCREF(Py_None);
1720 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001721#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001722 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1723 &path, &i))
1724 return NULL;
1725 Py_BEGIN_ALLOW_THREADS
1726 res = chmod(path, i);
1727 Py_END_ALLOW_THREADS
1728 if (res < 0)
1729 return posix_error_with_allocated_filename(path);
1730 PyMem_Free(path);
1731 Py_INCREF(Py_None);
1732 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001733#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001734}
1735
Christian Heimes36281872007-11-30 21:11:28 +00001736#ifdef HAVE_FCHMOD
1737PyDoc_STRVAR(posix_fchmod__doc__,
1738"fchmod(fd, mode)\n\n\
1739Change the access permissions of the file given by file\n\
1740descriptor fd.");
1741
1742static PyObject *
1743posix_fchmod(PyObject *self, PyObject *args)
1744{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001745 int fd, mode, res;
1746 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1747 return NULL;
1748 Py_BEGIN_ALLOW_THREADS
1749 res = fchmod(fd, mode);
1750 Py_END_ALLOW_THREADS
1751 if (res < 0)
1752 return posix_error();
1753 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001754}
1755#endif /* HAVE_FCHMOD */
1756
1757#ifdef HAVE_LCHMOD
1758PyDoc_STRVAR(posix_lchmod__doc__,
1759"lchmod(path, mode)\n\n\
1760Change the access permissions of a file. If path is a symlink, this\n\
1761affects the link itself rather than the target.");
1762
1763static PyObject *
1764posix_lchmod(PyObject *self, PyObject *args)
1765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001766 char *path = NULL;
1767 int i;
1768 int res;
1769 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1770 &path, &i))
1771 return NULL;
1772 Py_BEGIN_ALLOW_THREADS
1773 res = lchmod(path, i);
1774 Py_END_ALLOW_THREADS
1775 if (res < 0)
1776 return posix_error_with_allocated_filename(path);
1777 PyMem_Free(path);
1778 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001779}
1780#endif /* HAVE_LCHMOD */
1781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
Martin v. Löwis382abef2007-02-19 10:55:19 +00001783#ifdef HAVE_CHFLAGS
1784PyDoc_STRVAR(posix_chflags__doc__,
1785"chflags(path, flags)\n\n\
1786Set file flags.");
1787
1788static PyObject *
1789posix_chflags(PyObject *self, PyObject *args)
1790{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001791 char *path;
1792 unsigned long flags;
1793 int res;
1794 if (!PyArg_ParseTuple(args, "etk:chflags",
1795 Py_FileSystemDefaultEncoding, &path, &flags))
1796 return NULL;
1797 Py_BEGIN_ALLOW_THREADS
1798 res = chflags(path, flags);
1799 Py_END_ALLOW_THREADS
1800 if (res < 0)
1801 return posix_error_with_allocated_filename(path);
1802 PyMem_Free(path);
1803 Py_INCREF(Py_None);
1804 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001805}
1806#endif /* HAVE_CHFLAGS */
1807
1808#ifdef HAVE_LCHFLAGS
1809PyDoc_STRVAR(posix_lchflags__doc__,
1810"lchflags(path, flags)\n\n\
1811Set file flags.\n\
1812This function will not follow symbolic links.");
1813
1814static PyObject *
1815posix_lchflags(PyObject *self, PyObject *args)
1816{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001817 char *path;
1818 unsigned long flags;
1819 int res;
1820 if (!PyArg_ParseTuple(args, "etk:lchflags",
1821 Py_FileSystemDefaultEncoding, &path, &flags))
1822 return NULL;
1823 Py_BEGIN_ALLOW_THREADS
1824 res = lchflags(path, flags);
1825 Py_END_ALLOW_THREADS
1826 if (res < 0)
1827 return posix_error_with_allocated_filename(path);
1828 PyMem_Free(path);
1829 Py_INCREF(Py_None);
1830 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001831}
1832#endif /* HAVE_LCHFLAGS */
1833
Martin v. Löwis244edc82001-10-04 22:44:26 +00001834#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001838
1839static PyObject *
1840posix_chroot(PyObject *self, PyObject *args)
1841{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001842 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001843}
1844#endif
1845
Guido van Rossum21142a01999-01-08 21:05:37 +00001846#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001848"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001850
1851static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001852posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001853{
Stefan Krah93f7a322010-11-26 17:35:50 +00001854 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001855}
1856#endif /* HAVE_FSYNC */
1857
1858#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001859
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001860#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001861extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1862#endif
1863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001865"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001866force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001868
1869static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001870posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001871{
Stefan Krah93f7a322010-11-26 17:35:50 +00001872 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001873}
1874#endif /* HAVE_FDATASYNC */
1875
1876
Fredrik Lundh10723342000-07-10 16:38:09 +00001877#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001879"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001880Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001884{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001885 char *path = NULL;
1886 long uid, gid;
1887 int res;
1888 if (!PyArg_ParseTuple(args, "etll:chown",
1889 Py_FileSystemDefaultEncoding, &path,
1890 &uid, &gid))
1891 return NULL;
1892 Py_BEGIN_ALLOW_THREADS
1893 res = chown(path, (uid_t) uid, (gid_t) gid);
1894 Py_END_ALLOW_THREADS
1895 if (res < 0)
1896 return posix_error_with_allocated_filename(path);
1897 PyMem_Free(path);
1898 Py_INCREF(Py_None);
1899 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001900}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001901#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902
Christian Heimes36281872007-11-30 21:11:28 +00001903#ifdef HAVE_FCHOWN
1904PyDoc_STRVAR(posix_fchown__doc__,
1905"fchown(fd, uid, gid)\n\n\
1906Change the owner and group id of the file given by file descriptor\n\
1907fd to the numeric uid and gid.");
1908
1909static PyObject *
1910posix_fchown(PyObject *self, PyObject *args)
1911{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001912 int fd;
1913 long uid, gid;
1914 int res;
1915 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
1916 return NULL;
1917 Py_BEGIN_ALLOW_THREADS
1918 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1919 Py_END_ALLOW_THREADS
1920 if (res < 0)
1921 return posix_error();
1922 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001923}
1924#endif /* HAVE_FCHOWN */
1925
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001926#ifdef HAVE_LCHOWN
1927PyDoc_STRVAR(posix_lchown__doc__,
1928"lchown(path, uid, gid)\n\n\
1929Change the owner and group id of path to the numeric uid and gid.\n\
1930This function will not follow symbolic links.");
1931
1932static PyObject *
1933posix_lchown(PyObject *self, PyObject *args)
1934{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001935 char *path = NULL;
1936 long uid, gid;
1937 int res;
1938 if (!PyArg_ParseTuple(args, "etll:lchown",
1939 Py_FileSystemDefaultEncoding, &path,
1940 &uid, &gid))
1941 return NULL;
1942 Py_BEGIN_ALLOW_THREADS
1943 res = lchown(path, (uid_t) uid, (gid_t) gid);
1944 Py_END_ALLOW_THREADS
1945 if (res < 0)
1946 return posix_error_with_allocated_filename(path);
1947 PyMem_Free(path);
1948 Py_INCREF(Py_None);
1949 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001950}
1951#endif /* HAVE_LCHOWN */
1952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953
Guido van Rossum36bc6801995-06-14 22:54:23 +00001954#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001956"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Trent Nelsonda4277a2012-08-29 09:20:41 -04001959#if (defined(__sun) && defined(__SVR4)) || \
1960 defined(__OpenBSD__) || \
1961 defined(__NetBSD__)
Stefan Krah182ae642010-07-13 19:17:08 +00001962/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
1963static PyObject *
1964posix_getcwd(PyObject *self, PyObject *noargs)
1965{
1966 char buf[PATH_MAX+2];
1967 char *res;
1968
1969 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00001970 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00001971 Py_END_ALLOW_THREADS
1972
1973 if (res == NULL)
1974 return posix_error();
1975
1976 return PyString_FromString(buf);
1977}
1978#else
Barry Warsaw53699e91996-12-10 23:23:01 +00001979static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001980posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001981{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001982 int bufsize_incr = 1024;
1983 int bufsize = 0;
1984 char *tmpbuf = NULL;
1985 char *res = NULL;
1986 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001987
Victor Stinnerd6f85422010-05-05 23:33:33 +00001988 Py_BEGIN_ALLOW_THREADS
1989 do {
1990 bufsize = bufsize + bufsize_incr;
1991 tmpbuf = malloc(bufsize);
1992 if (tmpbuf == NULL) {
1993 break;
1994 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001995#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001996 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001997#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001998 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001999#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002000
Victor Stinnerd6f85422010-05-05 23:33:33 +00002001 if (res == NULL) {
2002 free(tmpbuf);
2003 }
2004 } while ((res == NULL) && (errno == ERANGE));
2005 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002006
Victor Stinnerd6f85422010-05-05 23:33:33 +00002007 if (res == NULL)
2008 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002009
Victor Stinnerd6f85422010-05-05 23:33:33 +00002010 dynamic_return = PyString_FromString(tmpbuf);
2011 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002012
Victor Stinnerd6f85422010-05-05 23:33:33 +00002013 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002014}
Stefan Krah182ae642010-07-13 19:17:08 +00002015#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002016
Walter Dörwald3b918c32002-11-21 20:18:46 +00002017#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002018PyDoc_STRVAR(posix_getcwdu__doc__,
2019"getcwdu() -> path\n\n\
2020Return a unicode string representing the current working directory.");
2021
2022static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002023posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002024{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002025 char buf[1026];
2026 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002027
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002028#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002029 DWORD len;
2030 wchar_t wbuf[1026];
2031 wchar_t *wbuf2 = wbuf;
2032 PyObject *resobj;
2033 Py_BEGIN_ALLOW_THREADS
2034 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2035 /* If the buffer is large enough, len does not include the
2036 terminating \0. If the buffer is too small, len includes
2037 the space needed for the terminator. */
2038 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2039 wbuf2 = malloc(len * sizeof(wchar_t));
2040 if (wbuf2)
2041 len = GetCurrentDirectoryW(len, wbuf2);
2042 }
2043 Py_END_ALLOW_THREADS
2044 if (!wbuf2) {
2045 PyErr_NoMemory();
2046 return NULL;
2047 }
2048 if (!len) {
2049 if (wbuf2 != wbuf) free(wbuf2);
2050 return win32_error("getcwdu", NULL);
2051 }
2052 resobj = PyUnicode_FromWideChar(wbuf2, len);
2053 if (wbuf2 != wbuf) free(wbuf2);
2054 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002055#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002056
Victor Stinnerd6f85422010-05-05 23:33:33 +00002057 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002058#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002059 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002060#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002061 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002062#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002063 Py_END_ALLOW_THREADS
2064 if (res == NULL)
2065 return posix_error();
2066 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002067}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002068#endif /* Py_USING_UNICODE */
2069#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002071
Guido van Rossumb6775db1994-08-01 11:34:53 +00002072#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002074"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Barry Warsaw53699e91996-12-10 23:23:01 +00002077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002078posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002080 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002082#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002086"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087Return a list containing the names of the entries in the directory.\n\
2088\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002089 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090\n\
2091The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002092entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Barry Warsaw53699e91996-12-10 23:23:01 +00002094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002095posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002096{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002097 /* XXX Should redo this putting the (now four) versions of opendir
2098 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002099#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002100
Victor Stinnerd6f85422010-05-05 23:33:33 +00002101 PyObject *d, *v;
2102 HANDLE hFindFile;
2103 BOOL result;
2104 WIN32_FIND_DATA FileData;
2105 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2106 char *bufptr = namebuf;
2107 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002108
Victor Stinnerd6f85422010-05-05 23:33:33 +00002109 PyObject *po;
2110 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2111 WIN32_FIND_DATAW wFileData;
2112 Py_UNICODE *wnamebuf;
2113 /* Overallocate for \\*.*\0 */
2114 len = PyUnicode_GET_SIZE(po);
2115 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2116 if (!wnamebuf) {
2117 PyErr_NoMemory();
2118 return NULL;
2119 }
2120 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2121 if (len > 0) {
2122 Py_UNICODE wch = wnamebuf[len-1];
2123 if (wch != L'/' && wch != L'\\' && wch != L':')
2124 wnamebuf[len++] = L'\\';
2125 wcscpy(wnamebuf + len, L"*.*");
2126 }
2127 if ((d = PyList_New(0)) == NULL) {
2128 free(wnamebuf);
2129 return NULL;
2130 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002131 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002132 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002133 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002134 if (hFindFile == INVALID_HANDLE_VALUE) {
2135 int error = GetLastError();
2136 if (error == ERROR_FILE_NOT_FOUND) {
2137 free(wnamebuf);
2138 return d;
2139 }
2140 Py_DECREF(d);
2141 win32_error_unicode("FindFirstFileW", wnamebuf);
2142 free(wnamebuf);
2143 return NULL;
2144 }
2145 do {
2146 /* Skip over . and .. */
2147 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2148 wcscmp(wFileData.cFileName, L"..") != 0) {
2149 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2150 if (v == NULL) {
2151 Py_DECREF(d);
2152 d = NULL;
2153 break;
2154 }
2155 if (PyList_Append(d, v) != 0) {
2156 Py_DECREF(v);
2157 Py_DECREF(d);
2158 d = NULL;
2159 break;
2160 }
2161 Py_DECREF(v);
2162 }
2163 Py_BEGIN_ALLOW_THREADS
2164 result = FindNextFileW(hFindFile, &wFileData);
2165 Py_END_ALLOW_THREADS
2166 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2167 it got to the end of the directory. */
2168 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2169 Py_DECREF(d);
2170 win32_error_unicode("FindNextFileW", wnamebuf);
2171 FindClose(hFindFile);
2172 free(wnamebuf);
2173 return NULL;
2174 }
2175 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002176
Victor Stinnerd6f85422010-05-05 23:33:33 +00002177 if (FindClose(hFindFile) == FALSE) {
2178 Py_DECREF(d);
2179 win32_error_unicode("FindClose", wnamebuf);
2180 free(wnamebuf);
2181 return NULL;
2182 }
2183 free(wnamebuf);
2184 return d;
2185 }
2186 /* Drop the argument parsing error as narrow strings
2187 are also valid. */
2188 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002189
Victor Stinnerd6f85422010-05-05 23:33:33 +00002190 if (!PyArg_ParseTuple(args, "et#:listdir",
2191 Py_FileSystemDefaultEncoding, &bufptr, &len))
2192 return NULL;
2193 if (len > 0) {
2194 char ch = namebuf[len-1];
2195 if (ch != SEP && ch != ALTSEP && ch != ':')
2196 namebuf[len++] = '/';
2197 strcpy(namebuf + len, "*.*");
2198 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002199
Victor Stinnerd6f85422010-05-05 23:33:33 +00002200 if ((d = PyList_New(0)) == NULL)
2201 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002202
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002203 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002205 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002206 if (hFindFile == INVALID_HANDLE_VALUE) {
2207 int error = GetLastError();
2208 if (error == ERROR_FILE_NOT_FOUND)
2209 return d;
2210 Py_DECREF(d);
2211 return win32_error("FindFirstFile", namebuf);
2212 }
2213 do {
2214 /* Skip over . and .. */
2215 if (strcmp(FileData.cFileName, ".") != 0 &&
2216 strcmp(FileData.cFileName, "..") != 0) {
2217 v = PyString_FromString(FileData.cFileName);
2218 if (v == NULL) {
2219 Py_DECREF(d);
2220 d = NULL;
2221 break;
2222 }
2223 if (PyList_Append(d, v) != 0) {
2224 Py_DECREF(v);
2225 Py_DECREF(d);
2226 d = NULL;
2227 break;
2228 }
2229 Py_DECREF(v);
2230 }
2231 Py_BEGIN_ALLOW_THREADS
2232 result = FindNextFile(hFindFile, &FileData);
2233 Py_END_ALLOW_THREADS
2234 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2235 it got to the end of the directory. */
2236 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2237 Py_DECREF(d);
2238 win32_error("FindNextFile", namebuf);
2239 FindClose(hFindFile);
2240 return NULL;
2241 }
2242 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002243
Victor Stinnerd6f85422010-05-05 23:33:33 +00002244 if (FindClose(hFindFile) == FALSE) {
2245 Py_DECREF(d);
2246 return win32_error("FindClose", namebuf);
2247 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002248
Victor Stinnerd6f85422010-05-05 23:33:33 +00002249 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002250
Tim Peters0bb44a42000-09-15 07:44:49 +00002251#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252
2253#ifndef MAX_PATH
2254#define MAX_PATH CCHMAXPATH
2255#endif
2256 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002257 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258 PyObject *d, *v;
2259 char namebuf[MAX_PATH+5];
2260 HDIR hdir = 1;
2261 ULONG srchcnt = 1;
2262 FILEFINDBUF3 ep;
2263 APIRET rc;
2264
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002265 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266 return NULL;
2267 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002268 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002269 return NULL;
2270 }
2271 strcpy(namebuf, name);
2272 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002273 if (*pt == ALTSEP)
2274 *pt = SEP;
2275 if (namebuf[len-1] != SEP)
2276 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277 strcpy(namebuf + len, "*.*");
2278
Victor Stinnerd6f85422010-05-05 23:33:33 +00002279 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002280 return NULL;
2281
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002282 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2283 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002285 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2286 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2287 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
2289 if (rc != NO_ERROR) {
2290 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002291 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292 }
2293
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002294 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295 do {
2296 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002297 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002298 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299
2300 strcpy(namebuf, ep.achName);
2301
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002302 /* Leave Case of Name Alone -- In Native Form */
2303 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002305 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306 if (v == NULL) {
2307 Py_DECREF(d);
2308 d = NULL;
2309 break;
2310 }
2311 if (PyList_Append(d, v) != 0) {
2312 Py_DECREF(v);
2313 Py_DECREF(d);
2314 d = NULL;
2315 break;
2316 }
2317 Py_DECREF(v);
2318 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2319 }
2320
2321 return d;
2322#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002323
Victor Stinnerd6f85422010-05-05 23:33:33 +00002324 char *name = NULL;
2325 PyObject *d, *v;
2326 DIR *dirp;
2327 struct dirent *ep;
2328 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002329
Victor Stinnerd6f85422010-05-05 23:33:33 +00002330 errno = 0;
2331 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2332 arg_is_unicode = 0;
2333 PyErr_Clear();
2334 }
2335 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2336 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002337 Py_BEGIN_ALLOW_THREADS
2338 dirp = opendir(name);
2339 Py_END_ALLOW_THREADS
2340 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002341 return posix_error_with_allocated_filename(name);
2342 }
2343 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002344 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002345 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002346 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002347 PyMem_Free(name);
2348 return NULL;
2349 }
2350 for (;;) {
2351 errno = 0;
2352 Py_BEGIN_ALLOW_THREADS
2353 ep = readdir(dirp);
2354 Py_END_ALLOW_THREADS
2355 if (ep == NULL) {
2356 if (errno == 0) {
2357 break;
2358 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002359 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002360 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002361 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002362 Py_DECREF(d);
2363 return posix_error_with_allocated_filename(name);
2364 }
2365 }
2366 if (ep->d_name[0] == '.' &&
2367 (NAMLEN(ep) == 1 ||
2368 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2369 continue;
2370 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2371 if (v == NULL) {
2372 Py_DECREF(d);
2373 d = NULL;
2374 break;
2375 }
Just van Rossum46c97842003-02-25 21:42:15 +00002376#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002377 if (arg_is_unicode) {
2378 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002379
Victor Stinnerd6f85422010-05-05 23:33:33 +00002380 w = PyUnicode_FromEncodedObject(v,
2381 Py_FileSystemDefaultEncoding,
2382 "strict");
2383 if (w != NULL) {
2384 Py_DECREF(v);
2385 v = w;
2386 }
2387 else {
2388 /* fall back to the original byte string, as
2389 discussed in patch #683592 */
2390 PyErr_Clear();
2391 }
2392 }
Just van Rossum46c97842003-02-25 21:42:15 +00002393#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002394 if (PyList_Append(d, v) != 0) {
2395 Py_DECREF(v);
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 Py_DECREF(v);
2401 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002402 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002403 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002404 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002405 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002406
Victor Stinnerd6f85422010-05-05 23:33:33 +00002407 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002408
Tim Peters0bb44a42000-09-15 07:44:49 +00002409#endif /* which OS */
2410} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002411
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002412#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002413/* A helper function for abspath on win32 */
2414static PyObject *
2415posix__getfullpathname(PyObject *self, PyObject *args)
2416{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002417 /* assume encoded strings won't more than double no of chars */
2418 char inbuf[MAX_PATH*2];
2419 char *inbufp = inbuf;
2420 Py_ssize_t insize = sizeof(inbuf);
2421 char outbuf[MAX_PATH*2];
2422 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002423
Victor Stinnerd6f85422010-05-05 23:33:33 +00002424 PyUnicodeObject *po;
2425 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2426 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2427 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2428 Py_UNICODE *wtemp;
2429 DWORD result;
2430 PyObject *v;
2431 result = GetFullPathNameW(wpath,
2432 sizeof(woutbuf)/sizeof(woutbuf[0]),
2433 woutbuf, &wtemp);
2434 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2435 woutbufp = malloc(result * sizeof(Py_UNICODE));
2436 if (!woutbufp)
2437 return PyErr_NoMemory();
2438 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2439 }
2440 if (result)
2441 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2442 else
2443 v = win32_error_unicode("GetFullPathNameW", wpath);
2444 if (woutbufp != woutbuf)
2445 free(woutbufp);
2446 return v;
2447 }
2448 /* Drop the argument parsing error as narrow strings
2449 are also valid. */
2450 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002451
Victor Stinnerd6f85422010-05-05 23:33:33 +00002452 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2453 Py_FileSystemDefaultEncoding, &inbufp,
2454 &insize))
2455 return NULL;
2456 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2457 outbuf, &temp))
2458 return win32_error("GetFullPathName", inbuf);
2459 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2460 return PyUnicode_Decode(outbuf, strlen(outbuf),
2461 Py_FileSystemDefaultEncoding, NULL);
2462 }
2463 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002464} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002465#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002467PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002468"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002469Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002470
Barry Warsaw53699e91996-12-10 23:23:01 +00002471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002472posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002474 int res;
2475 char *path = NULL;
2476 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002477
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002478#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002479 PyUnicodeObject *po;
2480 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2481 Py_BEGIN_ALLOW_THREADS
2482 /* PyUnicode_AS_UNICODE OK without thread lock as
2483 it is a simple dereference. */
2484 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2485 Py_END_ALLOW_THREADS
2486 if (!res)
2487 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2488 Py_INCREF(Py_None);
2489 return Py_None;
2490 }
2491 /* Drop the argument parsing error as narrow strings
2492 are also valid. */
2493 PyErr_Clear();
2494 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2495 Py_FileSystemDefaultEncoding, &path, &mode))
2496 return NULL;
2497 Py_BEGIN_ALLOW_THREADS
2498 /* PyUnicode_AS_UNICODE OK without thread lock as
2499 it is a simple dereference. */
2500 res = CreateDirectoryA(path, NULL);
2501 Py_END_ALLOW_THREADS
2502 if (!res) {
2503 win32_error("mkdir", path);
2504 PyMem_Free(path);
2505 return NULL;
2506 }
2507 PyMem_Free(path);
2508 Py_INCREF(Py_None);
2509 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002510#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002511
Victor Stinnerd6f85422010-05-05 23:33:33 +00002512 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2513 Py_FileSystemDefaultEncoding, &path, &mode))
2514 return NULL;
2515 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002516#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002518#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002519 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002520#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002521 Py_END_ALLOW_THREADS
2522 if (res < 0)
2523 return posix_error_with_allocated_filename(path);
2524 PyMem_Free(path);
2525 Py_INCREF(Py_None);
2526 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002527#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002528}
2529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002530
Neal Norwitz1818ed72006-03-26 00:29:48 +00002531/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2532#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002533#include <sys/resource.h>
2534#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002535
Neal Norwitz1818ed72006-03-26 00:29:48 +00002536
2537#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002539"nice(inc) -> new_priority\n\n\
2540Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002541
Barry Warsaw53699e91996-12-10 23:23:01 +00002542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002543posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002544{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002545 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002546
Victor Stinnerd6f85422010-05-05 23:33:33 +00002547 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2548 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002549
Victor Stinnerd6f85422010-05-05 23:33:33 +00002550 /* There are two flavours of 'nice': one that returns the new
2551 priority (as required by almost all standards out there) and the
2552 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2553 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002554
Victor Stinnerd6f85422010-05-05 23:33:33 +00002555 If we are of the nice family that returns the new priority, we
2556 need to clear errno before the call, and check if errno is filled
2557 before calling posix_error() on a returnvalue of -1, because the
2558 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002559
Victor Stinnerd6f85422010-05-05 23:33:33 +00002560 errno = 0;
2561 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002562#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002563 if (value == 0)
2564 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002565#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002566 if (value == -1 && errno != 0)
2567 /* either nice() or getpriority() returned an error */
2568 return posix_error();
2569 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002570}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002571#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002573PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002574"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002575Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002576
Barry Warsaw53699e91996-12-10 23:23:01 +00002577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002578posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002579{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002580#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002581 PyObject *o1, *o2;
2582 char *p1, *p2;
2583 BOOL result;
2584 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2585 goto error;
2586 if (!convert_to_unicode(&o1))
2587 goto error;
2588 if (!convert_to_unicode(&o2)) {
2589 Py_DECREF(o1);
2590 goto error;
2591 }
2592 Py_BEGIN_ALLOW_THREADS
2593 result = MoveFileW(PyUnicode_AsUnicode(o1),
2594 PyUnicode_AsUnicode(o2));
2595 Py_END_ALLOW_THREADS
2596 Py_DECREF(o1);
2597 Py_DECREF(o2);
2598 if (!result)
2599 return win32_error("rename", NULL);
2600 Py_INCREF(Py_None);
2601 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002602error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002603 PyErr_Clear();
2604 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2605 return NULL;
2606 Py_BEGIN_ALLOW_THREADS
2607 result = MoveFileA(p1, p2);
2608 Py_END_ALLOW_THREADS
2609 if (!result)
2610 return win32_error("rename", NULL);
2611 Py_INCREF(Py_None);
2612 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002613#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002614 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002615#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002616}
2617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002619PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002620"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002621Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002622
Barry Warsaw53699e91996-12-10 23:23:01 +00002623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002624posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002625{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002627 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002628#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002629 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002630#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002631}
2632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002635"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002637
Barry Warsaw53699e91996-12-10 23:23:01 +00002638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002639posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002640{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002642 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002643#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002644 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002645#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002646}
2647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002648
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002649#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002651"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002652Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002653
Barry Warsaw53699e91996-12-10 23:23:01 +00002654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002655posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002656{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002657 char *command;
2658 long sts;
2659 if (!PyArg_ParseTuple(args, "s:system", &command))
2660 return NULL;
2661 Py_BEGIN_ALLOW_THREADS
2662 sts = system(command);
2663 Py_END_ALLOW_THREADS
2664 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002666#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002670"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002671Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002672
Barry Warsaw53699e91996-12-10 23:23:01 +00002673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002674posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002675{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002676 int i;
2677 if (!PyArg_ParseTuple(args, "i:umask", &i))
2678 return NULL;
2679 i = (int)umask(i);
2680 if (i < 0)
2681 return posix_error();
2682 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002683}
2684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002687"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002688Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002690PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002691"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002692Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002693
Barry Warsaw53699e91996-12-10 23:23:01 +00002694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002695posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002696{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002698 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002699#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002700 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002701#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002702}
2703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002704
Guido van Rossumb6775db1994-08-01 11:34:53 +00002705#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002707"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002711posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002712{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002713 struct utsname u;
2714 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002715
Victor Stinnerd6f85422010-05-05 23:33:33 +00002716 Py_BEGIN_ALLOW_THREADS
2717 res = uname(&u);
2718 Py_END_ALLOW_THREADS
2719 if (res < 0)
2720 return posix_error();
2721 return Py_BuildValue("(sssss)",
2722 u.sysname,
2723 u.nodename,
2724 u.release,
2725 u.version,
2726 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002727}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002728#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002729
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002730static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002731extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002732{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002733 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002734 if (PyFloat_Check(t)) {
2735 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002736 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002737 if (!intobj)
2738 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002739#if SIZEOF_TIME_T > SIZEOF_LONG
2740 intval = PyInt_AsUnsignedLongLongMask(intobj);
2741#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002743#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002744 Py_DECREF(intobj);
2745 if (intval == -1 && PyErr_Occurred())
2746 return -1;
2747 *sec = intval;
2748 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2749 if (*usec < 0)
2750 /* If rounding gave us a negative number,
2751 truncate. */
2752 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002753 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002754 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002755#if SIZEOF_TIME_T > SIZEOF_LONG
2756 intval = PyInt_AsUnsignedLongLongMask(t);
2757#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002758 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002759#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002760 if (intval == -1 && PyErr_Occurred())
2761 return -1;
2762 *sec = intval;
2763 *usec = 0;
2764 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002765}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002768"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002769utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002770Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002771second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002772
Barry Warsaw53699e91996-12-10 23:23:01 +00002773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002774posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002775{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002776#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002777 PyObject *arg;
2778 PyUnicodeObject *obwpath;
2779 wchar_t *wpath = NULL;
2780 char *apath = NULL;
2781 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002782 time_t atimesec, mtimesec;
2783 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002784 FILETIME atime, mtime;
2785 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002786
Victor Stinnerd6f85422010-05-05 23:33:33 +00002787 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2788 wpath = PyUnicode_AS_UNICODE(obwpath);
2789 Py_BEGIN_ALLOW_THREADS
2790 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2791 NULL, OPEN_EXISTING,
2792 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2793 Py_END_ALLOW_THREADS
2794 if (hFile == INVALID_HANDLE_VALUE)
2795 return win32_error_unicode("utime", wpath);
2796 } else
2797 /* Drop the argument parsing error as narrow strings
2798 are also valid. */
2799 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002800
Victor Stinnerd6f85422010-05-05 23:33:33 +00002801 if (!wpath) {
2802 if (!PyArg_ParseTuple(args, "etO:utime",
2803 Py_FileSystemDefaultEncoding, &apath, &arg))
2804 return NULL;
2805 Py_BEGIN_ALLOW_THREADS
2806 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2807 NULL, OPEN_EXISTING,
2808 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2809 Py_END_ALLOW_THREADS
2810 if (hFile == INVALID_HANDLE_VALUE) {
2811 win32_error("utime", apath);
2812 PyMem_Free(apath);
2813 return NULL;
2814 }
2815 PyMem_Free(apath);
2816 }
2817
2818 if (arg == Py_None) {
2819 SYSTEMTIME now;
2820 GetSystemTime(&now);
2821 if (!SystemTimeToFileTime(&now, &mtime) ||
2822 !SystemTimeToFileTime(&now, &atime)) {
2823 win32_error("utime", NULL);
2824 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00002825 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00002826 }
2827 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2828 PyErr_SetString(PyExc_TypeError,
2829 "utime() arg 2 must be a tuple (atime, mtime)");
2830 goto done;
2831 }
2832 else {
2833 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2834 &atimesec, &ausec) == -1)
2835 goto done;
2836 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2837 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2838 &mtimesec, &musec) == -1)
2839 goto done;
2840 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2841 }
2842 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2843 /* Avoid putting the file name into the error here,
2844 as that may confuse the user into believing that
2845 something is wrong with the file, when it also
2846 could be the time stamp that gives a problem. */
2847 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00002848 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002849 }
2850 Py_INCREF(Py_None);
2851 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002852done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002853 CloseHandle(hFile);
2854 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002855#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002856
Victor Stinnerd6f85422010-05-05 23:33:33 +00002857 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002858 time_t atime, mtime;
2859 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002860 int res;
2861 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002862
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002863#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002864 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002865#define ATIME buf[0].tv_sec
2866#define MTIME buf[1].tv_sec
2867#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002868/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002869 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002870#define ATIME buf.actime
2871#define MTIME buf.modtime
2872#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002873#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002874 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002875#define ATIME buf[0]
2876#define MTIME buf[1]
2877#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002878#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002879
Mark Hammond817c9292003-12-03 01:22:38 +00002880
Victor Stinnerd6f85422010-05-05 23:33:33 +00002881 if (!PyArg_ParseTuple(args, "etO:utime",
2882 Py_FileSystemDefaultEncoding, &path, &arg))
2883 return NULL;
2884 if (arg == Py_None) {
2885 /* optional time values not given */
2886 Py_BEGIN_ALLOW_THREADS
2887 res = utime(path, NULL);
2888 Py_END_ALLOW_THREADS
2889 }
2890 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2891 PyErr_SetString(PyExc_TypeError,
2892 "utime() arg 2 must be a tuple (atime, mtime)");
2893 PyMem_Free(path);
2894 return NULL;
2895 }
2896 else {
2897 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2898 &atime, &ausec) == -1) {
2899 PyMem_Free(path);
2900 return NULL;
2901 }
2902 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2903 &mtime, &musec) == -1) {
2904 PyMem_Free(path);
2905 return NULL;
2906 }
2907 ATIME = atime;
2908 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002909#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002910 buf[0].tv_usec = ausec;
2911 buf[1].tv_usec = musec;
2912 Py_BEGIN_ALLOW_THREADS
2913 res = utimes(path, buf);
2914 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002915#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002916 Py_BEGIN_ALLOW_THREADS
2917 res = utime(path, UTIME_ARG);
2918 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002919#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002920 }
2921 if (res < 0) {
2922 return posix_error_with_allocated_filename(path);
2923 }
2924 PyMem_Free(path);
2925 Py_INCREF(Py_None);
2926 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002927#undef UTIME_ARG
2928#undef ATIME
2929#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002930#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002931}
2932
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933
Guido van Rossum3b066191991-06-04 19:40:25 +00002934/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002935
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002937"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002938Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939
Barry Warsaw53699e91996-12-10 23:23:01 +00002940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002941posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002942{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002943 int sts;
2944 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2945 return NULL;
2946 _exit(sts);
2947 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002948}
2949
Martin v. Löwis114619e2002-10-07 06:44:21 +00002950#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2951static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002952free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002953{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002954 Py_ssize_t i;
2955 for (i = 0; i < count; i++)
2956 PyMem_Free(array[i]);
2957 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002958}
2959#endif
2960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002962#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002964"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002965Execute an executable path with arguments, replacing current process.\n\
2966\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002967 path: path of executable file\n\
2968 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Barry Warsaw53699e91996-12-10 23:23:01 +00002970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002971posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002973 char *path;
2974 PyObject *argv;
2975 char **argvlist;
2976 Py_ssize_t i, argc;
2977 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002978
Victor Stinnerd6f85422010-05-05 23:33:33 +00002979 /* execv has two arguments: (path, argv), where
2980 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002981
Victor Stinnerd6f85422010-05-05 23:33:33 +00002982 if (!PyArg_ParseTuple(args, "etO:execv",
2983 Py_FileSystemDefaultEncoding,
2984 &path, &argv))
2985 return NULL;
2986 if (PyList_Check(argv)) {
2987 argc = PyList_Size(argv);
2988 getitem = PyList_GetItem;
2989 }
2990 else if (PyTuple_Check(argv)) {
2991 argc = PyTuple_Size(argv);
2992 getitem = PyTuple_GetItem;
2993 }
2994 else {
2995 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2996 PyMem_Free(path);
2997 return NULL;
2998 }
2999 if (argc < 1) {
3000 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3001 PyMem_Free(path);
3002 return NULL;
3003 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003004
Victor Stinnerd6f85422010-05-05 23:33:33 +00003005 argvlist = PyMem_NEW(char *, argc+1);
3006 if (argvlist == NULL) {
3007 PyMem_Free(path);
3008 return PyErr_NoMemory();
3009 }
3010 for (i = 0; i < argc; i++) {
3011 if (!PyArg_Parse((*getitem)(argv, i), "et",
3012 Py_FileSystemDefaultEncoding,
3013 &argvlist[i])) {
3014 free_string_array(argvlist, i);
3015 PyErr_SetString(PyExc_TypeError,
3016 "execv() arg 2 must contain only strings");
3017 PyMem_Free(path);
3018 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003019
Victor Stinnerd6f85422010-05-05 23:33:33 +00003020 }
3021 }
3022 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003023
Victor Stinnerd6f85422010-05-05 23:33:33 +00003024 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003025
Victor Stinnerd6f85422010-05-05 23:33:33 +00003026 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003027
Victor Stinnerd6f85422010-05-05 23:33:33 +00003028 free_string_array(argvlist, argc);
3029 PyMem_Free(path);
3030 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003031}
3032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003034PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003035"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003036Execute a path with arguments and environment, replacing current process.\n\
3037\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003038 path: path of executable file\n\
3039 args: tuple or list of arguments\n\
3040 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Barry Warsaw53699e91996-12-10 23:23:01 +00003042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003043posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003044{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003045 char *path;
3046 PyObject *argv, *env;
3047 char **argvlist;
3048 char **envlist;
3049 PyObject *key, *val, *keys=NULL, *vals=NULL;
3050 Py_ssize_t i, pos, argc, envc;
3051 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3052 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053
Victor Stinnerd6f85422010-05-05 23:33:33 +00003054 /* execve has three arguments: (path, argv, env), where
3055 argv is a list or tuple of strings and env is a dictionary
3056 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003057
Victor Stinnerd6f85422010-05-05 23:33:33 +00003058 if (!PyArg_ParseTuple(args, "etOO:execve",
3059 Py_FileSystemDefaultEncoding,
3060 &path, &argv, &env))
3061 return NULL;
3062 if (PyList_Check(argv)) {
3063 argc = PyList_Size(argv);
3064 getitem = PyList_GetItem;
3065 }
3066 else if (PyTuple_Check(argv)) {
3067 argc = PyTuple_Size(argv);
3068 getitem = PyTuple_GetItem;
3069 }
3070 else {
3071 PyErr_SetString(PyExc_TypeError,
3072 "execve() arg 2 must be a tuple or list");
3073 goto fail_0;
3074 }
3075 if (!PyMapping_Check(env)) {
3076 PyErr_SetString(PyExc_TypeError,
3077 "execve() arg 3 must be a mapping object");
3078 goto fail_0;
3079 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003080
Victor Stinnerd6f85422010-05-05 23:33:33 +00003081 argvlist = PyMem_NEW(char *, argc+1);
3082 if (argvlist == NULL) {
3083 PyErr_NoMemory();
3084 goto fail_0;
3085 }
3086 for (i = 0; i < argc; i++) {
3087 if (!PyArg_Parse((*getitem)(argv, i),
3088 "et;execve() arg 2 must contain only strings",
3089 Py_FileSystemDefaultEncoding,
3090 &argvlist[i]))
3091 {
3092 lastarg = i;
3093 goto fail_1;
3094 }
3095 }
3096 lastarg = argc;
3097 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003098
Victor Stinnerd6f85422010-05-05 23:33:33 +00003099 i = PyMapping_Size(env);
3100 if (i < 0)
3101 goto fail_1;
3102 envlist = PyMem_NEW(char *, i + 1);
3103 if (envlist == NULL) {
3104 PyErr_NoMemory();
3105 goto fail_1;
3106 }
3107 envc = 0;
3108 keys = PyMapping_Keys(env);
3109 vals = PyMapping_Values(env);
3110 if (!keys || !vals)
3111 goto fail_2;
3112 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3113 PyErr_SetString(PyExc_TypeError,
3114 "execve(): env.keys() or env.values() is not a list");
3115 goto fail_2;
3116 }
Tim Peters5aa91602002-01-30 05:46:57 +00003117
Victor Stinnerd6f85422010-05-05 23:33:33 +00003118 for (pos = 0; pos < i; pos++) {
3119 char *p, *k, *v;
3120 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003121
Victor Stinnerd6f85422010-05-05 23:33:33 +00003122 key = PyList_GetItem(keys, pos);
3123 val = PyList_GetItem(vals, pos);
3124 if (!key || !val)
3125 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003126
Victor Stinnerd6f85422010-05-05 23:33:33 +00003127 if (!PyArg_Parse(
3128 key,
3129 "s;execve() arg 3 contains a non-string key",
3130 &k) ||
3131 !PyArg_Parse(
3132 val,
3133 "s;execve() arg 3 contains a non-string value",
3134 &v))
3135 {
3136 goto fail_2;
3137 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003138
3139#if defined(PYOS_OS2)
3140 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3141 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3142#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003143 len = PyString_Size(key) + PyString_Size(val) + 2;
3144 p = PyMem_NEW(char, len);
3145 if (p == NULL) {
3146 PyErr_NoMemory();
3147 goto fail_2;
3148 }
3149 PyOS_snprintf(p, len, "%s=%s", k, v);
3150 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003152 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003153#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003154 }
3155 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003156
Victor Stinnerd6f85422010-05-05 23:33:33 +00003157 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003158
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160
Victor Stinnerd6f85422010-05-05 23:33:33 +00003161 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003162
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003163 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003164 while (--envc >= 0)
3165 PyMem_DEL(envlist[envc]);
3166 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003167 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003168 free_string_array(argvlist, lastarg);
3169 Py_XDECREF(vals);
3170 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003171 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003172 PyMem_Free(path);
3173 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003174}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003175#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177
Guido van Rossuma1065681999-01-25 23:20:23 +00003178#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003180"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003181Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003182\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003183 mode: mode of process creation\n\
3184 path: path of executable file\n\
3185 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003186
3187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003188posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003189{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003190 char *path;
3191 PyObject *argv;
3192 char **argvlist;
3193 int mode, i;
3194 Py_ssize_t argc;
3195 Py_intptr_t spawnval;
3196 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003197
Victor Stinnerd6f85422010-05-05 23:33:33 +00003198 /* spawnv has three arguments: (mode, path, argv), where
3199 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003200
Victor Stinnerd6f85422010-05-05 23:33:33 +00003201 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3202 Py_FileSystemDefaultEncoding,
3203 &path, &argv))
3204 return NULL;
3205 if (PyList_Check(argv)) {
3206 argc = PyList_Size(argv);
3207 getitem = PyList_GetItem;
3208 }
3209 else if (PyTuple_Check(argv)) {
3210 argc = PyTuple_Size(argv);
3211 getitem = PyTuple_GetItem;
3212 }
3213 else {
3214 PyErr_SetString(PyExc_TypeError,
3215 "spawnv() arg 2 must be a tuple or list");
3216 PyMem_Free(path);
3217 return NULL;
3218 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003219
Victor Stinnerd6f85422010-05-05 23:33:33 +00003220 argvlist = PyMem_NEW(char *, argc+1);
3221 if (argvlist == NULL) {
3222 PyMem_Free(path);
3223 return PyErr_NoMemory();
3224 }
3225 for (i = 0; i < argc; i++) {
3226 if (!PyArg_Parse((*getitem)(argv, i), "et",
3227 Py_FileSystemDefaultEncoding,
3228 &argvlist[i])) {
3229 free_string_array(argvlist, i);
3230 PyErr_SetString(
3231 PyExc_TypeError,
3232 "spawnv() arg 2 must contain only strings");
3233 PyMem_Free(path);
3234 return NULL;
3235 }
3236 }
3237 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003238
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003239#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003240 Py_BEGIN_ALLOW_THREADS
3241 spawnval = spawnv(mode, path, argvlist);
3242 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003243#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003244 if (mode == _OLD_P_OVERLAY)
3245 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003246
Victor Stinnerd6f85422010-05-05 23:33:33 +00003247 Py_BEGIN_ALLOW_THREADS
3248 spawnval = _spawnv(mode, path, argvlist);
3249 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003250#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003251
Victor Stinnerd6f85422010-05-05 23:33:33 +00003252 free_string_array(argvlist, argc);
3253 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003254
Victor Stinnerd6f85422010-05-05 23:33:33 +00003255 if (spawnval == -1)
3256 return posix_error();
3257 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003258#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003259 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003260#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003261 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003262#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003263}
3264
3265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003266PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003267"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003268Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003269\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003270 mode: mode of process creation\n\
3271 path: path of executable file\n\
3272 args: tuple or list of arguments\n\
3273 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003274
3275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003276posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003278 char *path;
3279 PyObject *argv, *env;
3280 char **argvlist;
3281 char **envlist;
3282 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3283 int mode, pos, envc;
3284 Py_ssize_t argc, i;
3285 Py_intptr_t spawnval;
3286 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3287 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003288
Victor Stinnerd6f85422010-05-05 23:33:33 +00003289 /* spawnve has four arguments: (mode, path, argv, env), where
3290 argv is a list or tuple of strings and env is a dictionary
3291 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003292
Victor Stinnerd6f85422010-05-05 23:33:33 +00003293 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3294 Py_FileSystemDefaultEncoding,
3295 &path, &argv, &env))
3296 return NULL;
3297 if (PyList_Check(argv)) {
3298 argc = PyList_Size(argv);
3299 getitem = PyList_GetItem;
3300 }
3301 else if (PyTuple_Check(argv)) {
3302 argc = PyTuple_Size(argv);
3303 getitem = PyTuple_GetItem;
3304 }
3305 else {
3306 PyErr_SetString(PyExc_TypeError,
3307 "spawnve() arg 2 must be a tuple or list");
3308 goto fail_0;
3309 }
3310 if (!PyMapping_Check(env)) {
3311 PyErr_SetString(PyExc_TypeError,
3312 "spawnve() arg 3 must be a mapping object");
3313 goto fail_0;
3314 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003315
Victor Stinnerd6f85422010-05-05 23:33:33 +00003316 argvlist = PyMem_NEW(char *, argc+1);
3317 if (argvlist == NULL) {
3318 PyErr_NoMemory();
3319 goto fail_0;
3320 }
3321 for (i = 0; i < argc; i++) {
3322 if (!PyArg_Parse((*getitem)(argv, i),
3323 "et;spawnve() arg 2 must contain only strings",
3324 Py_FileSystemDefaultEncoding,
3325 &argvlist[i]))
3326 {
3327 lastarg = i;
3328 goto fail_1;
3329 }
3330 }
3331 lastarg = argc;
3332 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003333
Victor Stinnerd6f85422010-05-05 23:33:33 +00003334 i = PyMapping_Size(env);
3335 if (i < 0)
3336 goto fail_1;
3337 envlist = PyMem_NEW(char *, i + 1);
3338 if (envlist == NULL) {
3339 PyErr_NoMemory();
3340 goto fail_1;
3341 }
3342 envc = 0;
3343 keys = PyMapping_Keys(env);
3344 vals = PyMapping_Values(env);
3345 if (!keys || !vals)
3346 goto fail_2;
3347 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3348 PyErr_SetString(PyExc_TypeError,
3349 "spawnve(): env.keys() or env.values() is not a list");
3350 goto fail_2;
3351 }
Tim Peters5aa91602002-01-30 05:46:57 +00003352
Victor Stinnerd6f85422010-05-05 23:33:33 +00003353 for (pos = 0; pos < i; pos++) {
3354 char *p, *k, *v;
3355 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003356
Victor Stinnerd6f85422010-05-05 23:33:33 +00003357 key = PyList_GetItem(keys, pos);
3358 val = PyList_GetItem(vals, pos);
3359 if (!key || !val)
3360 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003361
Victor Stinnerd6f85422010-05-05 23:33:33 +00003362 if (!PyArg_Parse(
3363 key,
3364 "s;spawnve() arg 3 contains a non-string key",
3365 &k) ||
3366 !PyArg_Parse(
3367 val,
3368 "s;spawnve() arg 3 contains a non-string value",
3369 &v))
3370 {
3371 goto fail_2;
3372 }
3373 len = PyString_Size(key) + PyString_Size(val) + 2;
3374 p = PyMem_NEW(char, len);
3375 if (p == NULL) {
3376 PyErr_NoMemory();
3377 goto fail_2;
3378 }
3379 PyOS_snprintf(p, len, "%s=%s", k, v);
3380 envlist[envc++] = p;
3381 }
3382 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003383
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003384#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003385 Py_BEGIN_ALLOW_THREADS
3386 spawnval = spawnve(mode, path, argvlist, envlist);
3387 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003388#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003389 if (mode == _OLD_P_OVERLAY)
3390 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003391
Victor Stinnerd6f85422010-05-05 23:33:33 +00003392 Py_BEGIN_ALLOW_THREADS
3393 spawnval = _spawnve(mode, path, argvlist, envlist);
3394 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003395#endif
Tim Peters25059d32001-12-07 20:35:43 +00003396
Victor Stinnerd6f85422010-05-05 23:33:33 +00003397 if (spawnval == -1)
3398 (void) posix_error();
3399 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003400#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003401 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003402#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003403 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003404#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003405
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003406 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003407 while (--envc >= 0)
3408 PyMem_DEL(envlist[envc]);
3409 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003410 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003411 free_string_array(argvlist, lastarg);
3412 Py_XDECREF(vals);
3413 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003414 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003415 PyMem_Free(path);
3416 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003417}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003418
3419/* OS/2 supports spawnvp & spawnvpe natively */
3420#if defined(PYOS_OS2)
3421PyDoc_STRVAR(posix_spawnvp__doc__,
3422"spawnvp(mode, file, args)\n\n\
3423Execute the program 'file' in a new process, using the environment\n\
3424search path to find the file.\n\
3425\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003426 mode: mode of process creation\n\
3427 file: executable file name\n\
3428 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003429
3430static PyObject *
3431posix_spawnvp(PyObject *self, PyObject *args)
3432{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003433 char *path;
3434 PyObject *argv;
3435 char **argvlist;
3436 int mode, i, argc;
3437 Py_intptr_t spawnval;
3438 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003439
Victor Stinnerd6f85422010-05-05 23:33:33 +00003440 /* spawnvp has three arguments: (mode, path, argv), where
3441 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003442
Victor Stinnerd6f85422010-05-05 23:33:33 +00003443 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3444 Py_FileSystemDefaultEncoding,
3445 &path, &argv))
3446 return NULL;
3447 if (PyList_Check(argv)) {
3448 argc = PyList_Size(argv);
3449 getitem = PyList_GetItem;
3450 }
3451 else if (PyTuple_Check(argv)) {
3452 argc = PyTuple_Size(argv);
3453 getitem = PyTuple_GetItem;
3454 }
3455 else {
3456 PyErr_SetString(PyExc_TypeError,
3457 "spawnvp() arg 2 must be a tuple or list");
3458 PyMem_Free(path);
3459 return NULL;
3460 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003461
Victor Stinnerd6f85422010-05-05 23:33:33 +00003462 argvlist = PyMem_NEW(char *, argc+1);
3463 if (argvlist == NULL) {
3464 PyMem_Free(path);
3465 return PyErr_NoMemory();
3466 }
3467 for (i = 0; i < argc; i++) {
3468 if (!PyArg_Parse((*getitem)(argv, i), "et",
3469 Py_FileSystemDefaultEncoding,
3470 &argvlist[i])) {
3471 free_string_array(argvlist, i);
3472 PyErr_SetString(
3473 PyExc_TypeError,
3474 "spawnvp() arg 2 must contain only strings");
3475 PyMem_Free(path);
3476 return NULL;
3477 }
3478 }
3479 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480
Victor Stinnerd6f85422010-05-05 23:33:33 +00003481 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003482#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003484#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003486#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003487 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003488
Victor Stinnerd6f85422010-05-05 23:33:33 +00003489 free_string_array(argvlist, argc);
3490 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003491
Victor Stinnerd6f85422010-05-05 23:33:33 +00003492 if (spawnval == -1)
3493 return posix_error();
3494 else
3495 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003496}
3497
3498
3499PyDoc_STRVAR(posix_spawnvpe__doc__,
3500"spawnvpe(mode, file, args, env)\n\n\
3501Execute the program 'file' in a new process, using the environment\n\
3502search path to find the file.\n\
3503\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003504 mode: mode of process creation\n\
3505 file: executable file name\n\
3506 args: tuple or list of arguments\n\
3507 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003508
3509static PyObject *
3510posix_spawnvpe(PyObject *self, PyObject *args)
3511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003512 char *path;
3513 PyObject *argv, *env;
3514 char **argvlist;
3515 char **envlist;
3516 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3517 int mode, i, pos, argc, envc;
3518 Py_intptr_t spawnval;
3519 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3520 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003521
Victor Stinnerd6f85422010-05-05 23:33:33 +00003522 /* spawnvpe has four arguments: (mode, path, argv, env), where
3523 argv is a list or tuple of strings and env is a dictionary
3524 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003525
Victor Stinnerd6f85422010-05-05 23:33:33 +00003526 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3527 Py_FileSystemDefaultEncoding,
3528 &path, &argv, &env))
3529 return NULL;
3530 if (PyList_Check(argv)) {
3531 argc = PyList_Size(argv);
3532 getitem = PyList_GetItem;
3533 }
3534 else if (PyTuple_Check(argv)) {
3535 argc = PyTuple_Size(argv);
3536 getitem = PyTuple_GetItem;
3537 }
3538 else {
3539 PyErr_SetString(PyExc_TypeError,
3540 "spawnvpe() arg 2 must be a tuple or list");
3541 goto fail_0;
3542 }
3543 if (!PyMapping_Check(env)) {
3544 PyErr_SetString(PyExc_TypeError,
3545 "spawnvpe() arg 3 must be a mapping object");
3546 goto fail_0;
3547 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003548
Victor Stinnerd6f85422010-05-05 23:33:33 +00003549 argvlist = PyMem_NEW(char *, argc+1);
3550 if (argvlist == NULL) {
3551 PyErr_NoMemory();
3552 goto fail_0;
3553 }
3554 for (i = 0; i < argc; i++) {
3555 if (!PyArg_Parse((*getitem)(argv, i),
3556 "et;spawnvpe() arg 2 must contain only strings",
3557 Py_FileSystemDefaultEncoding,
3558 &argvlist[i]))
3559 {
3560 lastarg = i;
3561 goto fail_1;
3562 }
3563 }
3564 lastarg = argc;
3565 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003566
Victor Stinnerd6f85422010-05-05 23:33:33 +00003567 i = PyMapping_Size(env);
3568 if (i < 0)
3569 goto fail_1;
3570 envlist = PyMem_NEW(char *, i + 1);
3571 if (envlist == NULL) {
3572 PyErr_NoMemory();
3573 goto fail_1;
3574 }
3575 envc = 0;
3576 keys = PyMapping_Keys(env);
3577 vals = PyMapping_Values(env);
3578 if (!keys || !vals)
3579 goto fail_2;
3580 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3581 PyErr_SetString(PyExc_TypeError,
3582 "spawnvpe(): env.keys() or env.values() is not a list");
3583 goto fail_2;
3584 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003585
Victor Stinnerd6f85422010-05-05 23:33:33 +00003586 for (pos = 0; pos < i; pos++) {
3587 char *p, *k, *v;
3588 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003589
Victor Stinnerd6f85422010-05-05 23:33:33 +00003590 key = PyList_GetItem(keys, pos);
3591 val = PyList_GetItem(vals, pos);
3592 if (!key || !val)
3593 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003594
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 if (!PyArg_Parse(
3596 key,
3597 "s;spawnvpe() arg 3 contains a non-string key",
3598 &k) ||
3599 !PyArg_Parse(
3600 val,
3601 "s;spawnvpe() arg 3 contains a non-string value",
3602 &v))
3603 {
3604 goto fail_2;
3605 }
3606 len = PyString_Size(key) + PyString_Size(val) + 2;
3607 p = PyMem_NEW(char, len);
3608 if (p == NULL) {
3609 PyErr_NoMemory();
3610 goto fail_2;
3611 }
3612 PyOS_snprintf(p, len, "%s=%s", k, v);
3613 envlist[envc++] = p;
3614 }
3615 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003616
Victor Stinnerd6f85422010-05-05 23:33:33 +00003617 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003618#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003619 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003621 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003624
Victor Stinnerd6f85422010-05-05 23:33:33 +00003625 if (spawnval == -1)
3626 (void) posix_error();
3627 else
3628 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003629
3630 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003631 while (--envc >= 0)
3632 PyMem_DEL(envlist[envc]);
3633 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003634 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003635 free_string_array(argvlist, lastarg);
3636 Py_XDECREF(vals);
3637 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003638 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003639 PyMem_Free(path);
3640 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003641}
3642#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003643#endif /* HAVE_SPAWNV */
3644
3645
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003646#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003647PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003648"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003649Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3650\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003651Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003652
3653static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003654posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003655{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003656 pid_t pid;
3657 int result = 0;
3658 _PyImport_AcquireLock();
3659 pid = fork1();
3660 if (pid == 0) {
3661 /* child: this clobbers and resets the import lock. */
3662 PyOS_AfterFork();
3663 } else {
3664 /* parent: release the import lock. */
3665 result = _PyImport_ReleaseLock();
3666 }
3667 if (pid == -1)
3668 return posix_error();
3669 if (result < 0) {
3670 /* Don't clobber the OSError if the fork failed. */
3671 PyErr_SetString(PyExc_RuntimeError,
3672 "not holding the import lock");
3673 return NULL;
3674 }
3675 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003676}
3677#endif
3678
3679
Guido van Rossumad0ee831995-03-01 10:34:45 +00003680#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003681PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003682"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003684Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003685
Barry Warsaw53699e91996-12-10 23:23:01 +00003686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003687posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003688{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003689 pid_t pid;
3690 int result = 0;
3691 _PyImport_AcquireLock();
3692 pid = fork();
3693 if (pid == 0) {
3694 /* child: this clobbers and resets the import lock. */
3695 PyOS_AfterFork();
3696 } else {
3697 /* parent: release the import lock. */
3698 result = _PyImport_ReleaseLock();
3699 }
3700 if (pid == -1)
3701 return posix_error();
3702 if (result < 0) {
3703 /* Don't clobber the OSError if the fork failed. */
3704 PyErr_SetString(PyExc_RuntimeError,
3705 "not holding the import lock");
3706 return NULL;
3707 }
3708 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003709}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003710#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003711
Neal Norwitzb59798b2003-03-21 01:43:31 +00003712/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003713/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3714#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003715#define DEV_PTY_FILE "/dev/ptc"
3716#define HAVE_DEV_PTMX
3717#else
3718#define DEV_PTY_FILE "/dev/ptmx"
3719#endif
3720
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003721#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003722#ifdef HAVE_PTY_H
3723#include <pty.h>
3724#else
3725#ifdef HAVE_LIBUTIL_H
3726#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003727#else
3728#ifdef HAVE_UTIL_H
3729#include <util.h>
3730#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731#endif /* HAVE_LIBUTIL_H */
3732#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003733#ifdef HAVE_STROPTS_H
3734#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003735#endif
3736#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003737
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003738#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003740"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003741Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003742
3743static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003744posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003745{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003746 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003747#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003748 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003749#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003750#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003751 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003752#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003753 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003754#endif
3755#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003756
Thomas Wouters70c21a12000-07-14 14:28:33 +00003757#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003758 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3759 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003760#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003761 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3762 if (slave_name == NULL)
3763 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003764
Victor Stinnerd6f85422010-05-05 23:33:33 +00003765 slave_fd = open(slave_name, O_RDWR);
3766 if (slave_fd < 0)
3767 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003768#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003769 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3770 if (master_fd < 0)
3771 return posix_error();
3772 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3773 /* change permission of slave */
3774 if (grantpt(master_fd) < 0) {
3775 PyOS_setsig(SIGCHLD, sig_saved);
3776 return posix_error();
3777 }
3778 /* unlock slave */
3779 if (unlockpt(master_fd) < 0) {
3780 PyOS_setsig(SIGCHLD, sig_saved);
3781 return posix_error();
3782 }
3783 PyOS_setsig(SIGCHLD, sig_saved);
3784 slave_name = ptsname(master_fd); /* get name of slave */
3785 if (slave_name == NULL)
3786 return posix_error();
3787 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3788 if (slave_fd < 0)
3789 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003790#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003791 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3792 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003793#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003794 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003795#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003796#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003797#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003798
Victor Stinnerd6f85422010-05-05 23:33:33 +00003799 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003800
Fred Drake8cef4cf2000-06-28 16:40:38 +00003801}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003802#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003803
3804#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003805PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003806"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003807Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3808Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003810
3811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003812posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003813{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003814 int master_fd = -1, result = 0;
3815 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003816
Victor Stinnerd6f85422010-05-05 23:33:33 +00003817 _PyImport_AcquireLock();
3818 pid = forkpty(&master_fd, NULL, NULL, NULL);
3819 if (pid == 0) {
3820 /* child: this clobbers and resets the import lock. */
3821 PyOS_AfterFork();
3822 } else {
3823 /* parent: release the import lock. */
3824 result = _PyImport_ReleaseLock();
3825 }
3826 if (pid == -1)
3827 return posix_error();
3828 if (result < 0) {
3829 /* Don't clobber the OSError if the fork failed. */
3830 PyErr_SetString(PyExc_RuntimeError,
3831 "not holding the import lock");
3832 return NULL;
3833 }
3834 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003835}
3836#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003837
Guido van Rossumad0ee831995-03-01 10:34:45 +00003838#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003840"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842
Barry Warsaw53699e91996-12-10 23:23:01 +00003843static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003844posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003845{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003846 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003847}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003848#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003850
Guido van Rossumad0ee831995-03-01 10:34:45 +00003851#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003853"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003854Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Barry Warsaw53699e91996-12-10 23:23:01 +00003856static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003857posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003858{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003859 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003860}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003861#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Guido van Rossumad0ee831995-03-01 10:34:45 +00003864#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003866"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003868
Barry Warsaw53699e91996-12-10 23:23:01 +00003869static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003870posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003871{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003872 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003873}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003874#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003878"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Barry Warsaw53699e91996-12-10 23:23:01 +00003881static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003882posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003883{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003884 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003885}
3886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887
Fred Drakec9680921999-12-13 16:37:25 +00003888#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003892
3893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003894posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003895{
3896 PyObject *result = NULL;
3897
Fred Drakec9680921999-12-13 16:37:25 +00003898#ifdef NGROUPS_MAX
3899#define MAX_GROUPS NGROUPS_MAX
3900#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003901 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003902#define MAX_GROUPS 64
3903#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003904 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003905
Victor Stinner59729ff2011-07-05 11:28:19 +02003906 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003907 * This is a helper variable to store the intermediate result when
3908 * that happens.
3909 *
3910 * To keep the code readable the OSX behaviour is unconditional,
3911 * according to the POSIX spec this should be safe on all unix-y
3912 * systems.
3913 */
3914 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003915 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003916
Victor Stinnerd6f85422010-05-05 23:33:33 +00003917 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003918 if (n < 0) {
3919 if (errno == EINVAL) {
3920 n = getgroups(0, NULL);
3921 if (n == -1) {
3922 return posix_error();
3923 }
3924 if (n == 0) {
3925 /* Avoid malloc(0) */
3926 alt_grouplist = grouplist;
3927 } else {
3928 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
3929 if (alt_grouplist == NULL) {
3930 errno = EINVAL;
3931 return posix_error();
3932 }
3933 n = getgroups(n, alt_grouplist);
3934 if (n == -1) {
3935 PyMem_Free(alt_grouplist);
3936 return posix_error();
3937 }
3938 }
3939 } else {
3940 return posix_error();
3941 }
3942 }
3943 result = PyList_New(n);
3944 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00003945 int i;
3946 for (i = 0; i < n; ++i) {
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003947 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003948 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00003949 Py_DECREF(result);
3950 result = NULL;
3951 break;
Fred Drakec9680921999-12-13 16:37:25 +00003952 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003953 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003954 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003955 }
3956
3957 if (alt_grouplist != grouplist) {
3958 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003959 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003960
Fred Drakec9680921999-12-13 16:37:25 +00003961 return result;
3962}
3963#endif
3964
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003965#ifdef HAVE_INITGROUPS
3966PyDoc_STRVAR(posix_initgroups__doc__,
3967"initgroups(username, gid) -> None\n\n\
3968Call the system initgroups() to initialize the group access list with all of\n\
3969the groups of which the specified username is a member, plus the specified\n\
3970group id.");
3971
3972static PyObject *
3973posix_initgroups(PyObject *self, PyObject *args)
3974{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003975 char *username;
3976 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003977
Victor Stinnerd6f85422010-05-05 23:33:33 +00003978 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3979 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003980
Victor Stinnerd6f85422010-05-05 23:33:33 +00003981 if (initgroups(username, (gid_t) gid) == -1)
3982 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003983
Victor Stinnerd6f85422010-05-05 23:33:33 +00003984 Py_INCREF(Py_None);
3985 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003986}
3987#endif
3988
Martin v. Löwis606edc12002-06-13 21:09:11 +00003989#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003990PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003991"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003992Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003993
3994static PyObject *
3995posix_getpgid(PyObject *self, PyObject *args)
3996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 pid_t pid, pgid;
3998 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3999 return NULL;
4000 pgid = getpgid(pid);
4001 if (pgid < 0)
4002 return posix_error();
4003 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004004}
4005#endif /* HAVE_GETPGID */
4006
4007
Guido van Rossumb6775db1994-08-01 11:34:53 +00004008#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Barry Warsaw53699e91996-12-10 23:23:01 +00004013static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004014posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004015{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004016#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004017 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004018#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004019 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004020#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004021}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004022#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004024
Guido van Rossumb6775db1994-08-01 11:34:53 +00004025#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004026PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004027"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004028Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004029
Barry Warsaw53699e91996-12-10 23:23:01 +00004030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004031posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004032{
Guido van Rossum64933891994-10-20 21:56:42 +00004033#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004034 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004035#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004036 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004037#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004038 return posix_error();
4039 Py_INCREF(Py_None);
4040 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004041}
4042
Guido van Rossumb6775db1994-08-01 11:34:53 +00004043#endif /* HAVE_SETPGRP */
4044
Guido van Rossumad0ee831995-03-01 10:34:45 +00004045#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004047"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004048Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Barry Warsaw53699e91996-12-10 23:23:01 +00004050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004051posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004052{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004053 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004055#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
Fred Drake12c6e2d1999-12-14 21:25:03 +00004058#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004060"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004062
4063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004064posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004065{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004066 PyObject *result = NULL;
4067 char *name;
4068 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004069
Victor Stinnerd6f85422010-05-05 23:33:33 +00004070 errno = 0;
4071 name = getlogin();
4072 if (name == NULL) {
4073 if (errno)
4074 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004075 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004076 PyErr_SetString(PyExc_OSError,
4077 "unable to determine login name");
4078 }
4079 else
4080 result = PyString_FromString(name);
4081 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004082
Fred Drake12c6e2d1999-12-14 21:25:03 +00004083 return result;
4084}
4085#endif
4086
Guido van Rossumad0ee831995-03-01 10:34:45 +00004087#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004089"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004090Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004091
Barry Warsaw53699e91996-12-10 23:23:01 +00004092static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004093posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004094{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004095 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004096}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004097#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004099
Guido van Rossumad0ee831995-03-01 10:34:45 +00004100#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004102"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Barry Warsaw53699e91996-12-10 23:23:01 +00004105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004106posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004107{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004108 pid_t pid;
4109 int sig;
4110 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4111 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004112#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004113 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4114 APIRET rc;
4115 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004116 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004117
4118 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4119 APIRET rc;
4120 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004121 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122
4123 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004124 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004125#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004126 if (kill(pid, sig) == -1)
4127 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004128#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004129 Py_INCREF(Py_None);
4130 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004131}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004132#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004133
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004134#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004136"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004138
4139static PyObject *
4140posix_killpg(PyObject *self, PyObject *args)
4141{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004142 int sig;
4143 pid_t pgid;
4144 /* XXX some man pages make the `pgid` parameter an int, others
4145 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4146 take the same type. Moreover, pid_t is always at least as wide as
4147 int (else compilation of this module fails), which is safe. */
4148 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4149 return NULL;
4150 if (killpg(pgid, sig) == -1)
4151 return posix_error();
4152 Py_INCREF(Py_None);
4153 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004154}
4155#endif
4156
Brian Curtine5aa8862010-04-02 23:26:06 +00004157#ifdef MS_WINDOWS
4158PyDoc_STRVAR(win32_kill__doc__,
4159"kill(pid, sig)\n\n\
4160Kill a process with a signal.");
4161
4162static PyObject *
4163win32_kill(PyObject *self, PyObject *args)
4164{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004165 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004166 DWORD pid, sig, err;
4167 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004168
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4170 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004171
Victor Stinnerd6f85422010-05-05 23:33:33 +00004172 /* Console processes which share a common console can be sent CTRL+C or
4173 CTRL+BREAK events, provided they handle said events. */
4174 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4175 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4176 err = GetLastError();
4177 return PyErr_SetFromWindowsErr(err);
4178 }
4179 else
4180 Py_RETURN_NONE;
4181 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004182
Victor Stinnerd6f85422010-05-05 23:33:33 +00004183 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4184 attempt to open and terminate the process. */
4185 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4186 if (handle == NULL) {
4187 err = GetLastError();
4188 return PyErr_SetFromWindowsErr(err);
4189 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004190
Victor Stinnerd6f85422010-05-05 23:33:33 +00004191 if (TerminateProcess(handle, sig) == 0) {
4192 err = GetLastError();
4193 result = PyErr_SetFromWindowsErr(err);
4194 } else {
4195 Py_INCREF(Py_None);
4196 result = Py_None;
4197 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004198
Victor Stinnerd6f85422010-05-05 23:33:33 +00004199 CloseHandle(handle);
4200 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004201}
Brian Curtincaea7e82011-06-08 19:29:53 -05004202
Brian Curtin5446f082011-06-09 10:00:42 -05004203PyDoc_STRVAR(posix__isdir__doc__,
4204"Return true if the pathname refers to an existing directory.");
4205
Brian Curtincaea7e82011-06-08 19:29:53 -05004206static PyObject *
4207posix__isdir(PyObject *self, PyObject *args)
4208{
4209 PyObject *opath;
4210 char *path;
4211 PyUnicodeObject *po;
4212 DWORD attributes;
4213
4214 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
4215 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
4216
4217 attributes = GetFileAttributesW(wpath);
4218 if (attributes == INVALID_FILE_ATTRIBUTES)
4219 Py_RETURN_FALSE;
4220 goto check;
4221 }
4222 /* Drop the argument parsing error as narrow strings
4223 are also valid. */
4224 PyErr_Clear();
4225
4226 if (!PyArg_ParseTuple(args, "et:_isdir",
4227 Py_FileSystemDefaultEncoding, &path))
4228 return NULL;
4229
4230 attributes = GetFileAttributesA(path);
4231 if (attributes == INVALID_FILE_ATTRIBUTES)
4232 Py_RETURN_FALSE;
4233
4234check:
4235 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4236 Py_RETURN_TRUE;
4237 else
4238 Py_RETURN_FALSE;
4239}
Brian Curtine5aa8862010-04-02 23:26:06 +00004240#endif /* MS_WINDOWS */
4241
Guido van Rossumc0125471996-06-28 18:55:32 +00004242#ifdef HAVE_PLOCK
4243
4244#ifdef HAVE_SYS_LOCK_H
4245#include <sys/lock.h>
4246#endif
4247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004248PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004249"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004250Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004251
Barry Warsaw53699e91996-12-10 23:23:01 +00004252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004253posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004254{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004255 int op;
4256 if (!PyArg_ParseTuple(args, "i:plock", &op))
4257 return NULL;
4258 if (plock(op) == -1)
4259 return posix_error();
4260 Py_INCREF(Py_None);
4261 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004262}
4263#endif
4264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004265
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004266#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004267PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004268"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004270
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004271#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004272#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004273static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004274async_system(const char *command)
4275{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004276 char errormsg[256], args[1024];
4277 RESULTCODES rcodes;
4278 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004279
Victor Stinnerd6f85422010-05-05 23:33:33 +00004280 char *shell = getenv("COMSPEC");
4281 if (!shell)
4282 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004283
Victor Stinnerd6f85422010-05-05 23:33:33 +00004284 /* avoid overflowing the argument buffer */
4285 if (strlen(shell) + 3 + strlen(command) >= 1024)
4286 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004287
Victor Stinnerd6f85422010-05-05 23:33:33 +00004288 args[0] = '\0';
4289 strcat(args, shell);
4290 strcat(args, "/c ");
4291 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004292
Victor Stinnerd6f85422010-05-05 23:33:33 +00004293 /* execute asynchronously, inheriting the environment */
4294 rc = DosExecPgm(errormsg,
4295 sizeof(errormsg),
4296 EXEC_ASYNC,
4297 args,
4298 NULL,
4299 &rcodes,
4300 shell);
4301 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004302}
4303
Guido van Rossumd48f2521997-12-05 22:19:34 +00004304static FILE *
4305popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004306{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004307 int oldfd, tgtfd;
4308 HFILE pipeh[2];
4309 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004310
Victor Stinnerd6f85422010-05-05 23:33:33 +00004311 /* mode determines which of stdin or stdout is reconnected to
4312 * the pipe to the child
4313 */
4314 if (strchr(mode, 'r') != NULL) {
4315 tgt_fd = 1; /* stdout */
4316 } else if (strchr(mode, 'w')) {
4317 tgt_fd = 0; /* stdin */
4318 } else {
4319 *err = ERROR_INVALID_ACCESS;
4320 return NULL;
4321 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004322
Victor Stinnerd6f85422010-05-05 23:33:33 +00004323 /* setup the pipe */
4324 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4325 *err = rc;
4326 return NULL;
4327 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004328
Victor Stinnerd6f85422010-05-05 23:33:33 +00004329 /* prevent other threads accessing stdio */
4330 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004331
Victor Stinnerd6f85422010-05-05 23:33:33 +00004332 /* reconnect stdio and execute child */
4333 oldfd = dup(tgtfd);
4334 close(tgtfd);
4335 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4336 DosClose(pipeh[tgtfd]);
4337 rc = async_system(command);
4338 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004339
Victor Stinnerd6f85422010-05-05 23:33:33 +00004340 /* restore stdio */
4341 dup2(oldfd, tgtfd);
4342 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004343
Victor Stinnerd6f85422010-05-05 23:33:33 +00004344 /* allow other threads access to stdio */
4345 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004346
Victor Stinnerd6f85422010-05-05 23:33:33 +00004347 /* if execution of child was successful return file stream */
4348 if (rc == NO_ERROR)
4349 return fdopen(pipeh[1 - tgtfd], mode);
4350 else {
4351 DosClose(pipeh[1 - tgtfd]);
4352 *err = rc;
4353 return NULL;
4354 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004355}
4356
4357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004358posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004359{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004360 char *name;
4361 char *mode = "r";
4362 int err, bufsize = -1;
4363 FILE *fp;
4364 PyObject *f;
4365 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4366 return NULL;
4367 Py_BEGIN_ALLOW_THREADS
4368 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4369 Py_END_ALLOW_THREADS
4370 if (fp == NULL)
4371 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004372
Victor Stinnerd6f85422010-05-05 23:33:33 +00004373 f = PyFile_FromFile(fp, name, mode, fclose);
4374 if (f != NULL)
4375 PyFile_SetBufSize(f, bufsize);
4376 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004377}
4378
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004379#elif defined(PYCC_GCC)
4380
4381/* standard posix version of popen() support */
4382static PyObject *
4383posix_popen(PyObject *self, PyObject *args)
4384{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004385 char *name;
4386 char *mode = "r";
4387 int bufsize = -1;
4388 FILE *fp;
4389 PyObject *f;
4390 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4391 return NULL;
4392 Py_BEGIN_ALLOW_THREADS
4393 fp = popen(name, mode);
4394 Py_END_ALLOW_THREADS
4395 if (fp == NULL)
4396 return posix_error();
4397 f = PyFile_FromFile(fp, name, mode, pclose);
4398 if (f != NULL)
4399 PyFile_SetBufSize(f, bufsize);
4400 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004401}
4402
4403/* fork() under OS/2 has lots'o'warts
4404 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4405 * most of this code is a ripoff of the win32 code, but using the
4406 * capabilities of EMX's C library routines
4407 */
4408
4409/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4410#define POPEN_1 1
4411#define POPEN_2 2
4412#define POPEN_3 3
4413#define POPEN_4 4
4414
4415static PyObject *_PyPopen(char *, int, int, int);
4416static int _PyPclose(FILE *file);
4417
4418/*
4419 * Internal dictionary mapping popen* file pointers to process handles,
4420 * for use when retrieving the process exit code. See _PyPclose() below
4421 * for more information on this dictionary's use.
4422 */
4423static PyObject *_PyPopenProcs = NULL;
4424
4425/* os2emx version of popen2()
4426 *
4427 * The result of this function is a pipe (file) connected to the
4428 * process's stdin, and a pipe connected to the process's stdout.
4429 */
4430
4431static PyObject *
4432os2emx_popen2(PyObject *self, PyObject *args)
4433{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004434 PyObject *f;
4435 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004436
Victor Stinnerd6f85422010-05-05 23:33:33 +00004437 char *cmdstring;
4438 char *mode = "t";
4439 int bufsize = -1;
4440 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4441 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004442
Victor Stinnerd6f85422010-05-05 23:33:33 +00004443 if (*mode == 't')
4444 tm = O_TEXT;
4445 else if (*mode != 'b') {
4446 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4447 return NULL;
4448 } else
4449 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004450
Victor Stinnerd6f85422010-05-05 23:33:33 +00004451 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004452
Victor Stinnerd6f85422010-05-05 23:33:33 +00004453 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004454}
4455
4456/*
4457 * Variation on os2emx.popen2
4458 *
4459 * The result of this function is 3 pipes - the process's stdin,
4460 * stdout and stderr
4461 */
4462
4463static PyObject *
4464os2emx_popen3(PyObject *self, PyObject *args)
4465{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004466 PyObject *f;
4467 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004468
Victor Stinnerd6f85422010-05-05 23:33:33 +00004469 char *cmdstring;
4470 char *mode = "t";
4471 int bufsize = -1;
4472 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4473 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004474
Victor Stinnerd6f85422010-05-05 23:33:33 +00004475 if (*mode == 't')
4476 tm = O_TEXT;
4477 else if (*mode != 'b') {
4478 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4479 return NULL;
4480 } else
4481 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004482
Victor Stinnerd6f85422010-05-05 23:33:33 +00004483 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004484
Victor Stinnerd6f85422010-05-05 23:33:33 +00004485 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004486}
4487
4488/*
4489 * Variation on os2emx.popen2
4490 *
Tim Peters11b23062003-04-23 02:39:17 +00004491 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004492 * and stdout+stderr combined as a single pipe.
4493 */
4494
4495static PyObject *
4496os2emx_popen4(PyObject *self, PyObject *args)
4497{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004498 PyObject *f;
4499 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004500
Victor Stinnerd6f85422010-05-05 23:33:33 +00004501 char *cmdstring;
4502 char *mode = "t";
4503 int bufsize = -1;
4504 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4505 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004506
Victor Stinnerd6f85422010-05-05 23:33:33 +00004507 if (*mode == 't')
4508 tm = O_TEXT;
4509 else if (*mode != 'b') {
4510 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4511 return NULL;
4512 } else
4513 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004514
Victor Stinnerd6f85422010-05-05 23:33:33 +00004515 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004516
Victor Stinnerd6f85422010-05-05 23:33:33 +00004517 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004518}
4519
4520/* a couple of structures for convenient handling of multiple
4521 * file handles and pipes
4522 */
4523struct file_ref
4524{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004525 int handle;
4526 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004527};
4528
4529struct pipe_ref
4530{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004531 int rd;
4532 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004533};
4534
4535/* The following code is derived from the win32 code */
4536
4537static PyObject *
4538_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4539{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004540 struct file_ref stdio[3];
4541 struct pipe_ref p_fd[3];
4542 FILE *p_s[3];
4543 int file_count, i, pipe_err;
4544 pid_t pipe_pid;
4545 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4546 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004547
Victor Stinnerd6f85422010-05-05 23:33:33 +00004548 /* file modes for subsequent fdopen's on pipe handles */
4549 if (mode == O_TEXT)
4550 {
4551 rd_mode = "rt";
4552 wr_mode = "wt";
4553 }
4554 else
4555 {
4556 rd_mode = "rb";
4557 wr_mode = "wb";
4558 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004559
Victor Stinnerd6f85422010-05-05 23:33:33 +00004560 /* prepare shell references */
4561 if ((shell = getenv("EMXSHELL")) == NULL)
4562 if ((shell = getenv("COMSPEC")) == NULL)
4563 {
4564 errno = ENOENT;
4565 return posix_error();
4566 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004567
Victor Stinnerd6f85422010-05-05 23:33:33 +00004568 sh_name = _getname(shell);
4569 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4570 opt = "/c";
4571 else
4572 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004573
Victor Stinnerd6f85422010-05-05 23:33:33 +00004574 /* save current stdio fds + their flags, and set not inheritable */
4575 i = pipe_err = 0;
4576 while (pipe_err >= 0 && i < 3)
4577 {
4578 pipe_err = stdio[i].handle = dup(i);
4579 stdio[i].flags = fcntl(i, F_GETFD, 0);
4580 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4581 i++;
4582 }
4583 if (pipe_err < 0)
4584 {
4585 /* didn't get them all saved - clean up and bail out */
4586 int saved_err = errno;
4587 while (i-- > 0)
4588 {
4589 close(stdio[i].handle);
4590 }
4591 errno = saved_err;
4592 return posix_error();
4593 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004594
Victor Stinnerd6f85422010-05-05 23:33:33 +00004595 /* create pipe ends */
4596 file_count = 2;
4597 if (n == POPEN_3)
4598 file_count = 3;
4599 i = pipe_err = 0;
4600 while ((pipe_err == 0) && (i < file_count))
4601 pipe_err = pipe((int *)&p_fd[i++]);
4602 if (pipe_err < 0)
4603 {
4604 /* didn't get them all made - clean up and bail out */
4605 while (i-- > 0)
4606 {
4607 close(p_fd[i].wr);
4608 close(p_fd[i].rd);
4609 }
4610 errno = EPIPE;
4611 return posix_error();
4612 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004613
Victor Stinnerd6f85422010-05-05 23:33:33 +00004614 /* change the actual standard IO streams over temporarily,
4615 * making the retained pipe ends non-inheritable
4616 */
4617 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004618
Victor Stinnerd6f85422010-05-05 23:33:33 +00004619 /* - stdin */
4620 if (dup2(p_fd[0].rd, 0) == 0)
4621 {
4622 close(p_fd[0].rd);
4623 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4624 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4625 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4626 {
4627 close(p_fd[0].wr);
4628 pipe_err = -1;
4629 }
4630 }
4631 else
4632 {
4633 pipe_err = -1;
4634 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635
Victor Stinnerd6f85422010-05-05 23:33:33 +00004636 /* - stdout */
4637 if (pipe_err == 0)
4638 {
4639 if (dup2(p_fd[1].wr, 1) == 1)
4640 {
4641 close(p_fd[1].wr);
4642 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4643 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4644 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4645 {
4646 close(p_fd[1].rd);
4647 pipe_err = -1;
4648 }
4649 }
4650 else
4651 {
4652 pipe_err = -1;
4653 }
4654 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004655
Victor Stinnerd6f85422010-05-05 23:33:33 +00004656 /* - stderr, as required */
4657 if (pipe_err == 0)
4658 switch (n)
4659 {
4660 case POPEN_3:
4661 {
4662 if (dup2(p_fd[2].wr, 2) == 2)
4663 {
4664 close(p_fd[2].wr);
4665 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4666 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4667 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4668 {
4669 close(p_fd[2].rd);
4670 pipe_err = -1;
4671 }
4672 }
4673 else
4674 {
4675 pipe_err = -1;
4676 }
4677 break;
4678 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004679
Victor Stinnerd6f85422010-05-05 23:33:33 +00004680 case POPEN_4:
4681 {
4682 if (dup2(1, 2) != 2)
4683 {
4684 pipe_err = -1;
4685 }
4686 break;
4687 }
4688 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004689
Victor Stinnerd6f85422010-05-05 23:33:33 +00004690 /* spawn the child process */
4691 if (pipe_err == 0)
4692 {
4693 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4694 if (pipe_pid == -1)
4695 {
4696 pipe_err = -1;
4697 }
4698 else
4699 {
4700 /* save the PID into the FILE structure
4701 * NOTE: this implementation doesn't actually
4702 * take advantage of this, but do it for
4703 * completeness - AIM Apr01
4704 */
4705 for (i = 0; i < file_count; i++)
4706 p_s[i]->_pid = pipe_pid;
4707 }
4708 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004709
Victor Stinnerd6f85422010-05-05 23:33:33 +00004710 /* reset standard IO to normal */
4711 for (i = 0; i < 3; i++)
4712 {
4713 dup2(stdio[i].handle, i);
4714 fcntl(i, F_SETFD, stdio[i].flags);
4715 close(stdio[i].handle);
4716 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004717
Victor Stinnerd6f85422010-05-05 23:33:33 +00004718 /* if any remnant problems, clean up and bail out */
4719 if (pipe_err < 0)
4720 {
4721 for (i = 0; i < 3; i++)
4722 {
4723 close(p_fd[i].rd);
4724 close(p_fd[i].wr);
4725 }
4726 errno = EPIPE;
4727 return posix_error_with_filename(cmdstring);
4728 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004729
Victor Stinnerd6f85422010-05-05 23:33:33 +00004730 /* build tuple of file objects to return */
4731 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4732 PyFile_SetBufSize(p_f[0], bufsize);
4733 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4734 PyFile_SetBufSize(p_f[1], bufsize);
4735 if (n == POPEN_3)
4736 {
4737 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4738 PyFile_SetBufSize(p_f[0], bufsize);
4739 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4740 }
4741 else
4742 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004743
Victor Stinnerd6f85422010-05-05 23:33:33 +00004744 /*
4745 * Insert the files we've created into the process dictionary
4746 * all referencing the list with the process handle and the
4747 * initial number of files (see description below in _PyPclose).
4748 * Since if _PyPclose later tried to wait on a process when all
4749 * handles weren't closed, it could create a deadlock with the
4750 * child, we spend some energy here to try to ensure that we
4751 * either insert all file handles into the dictionary or none
4752 * at all. It's a little clumsy with the various popen modes
4753 * and variable number of files involved.
4754 */
4755 if (!_PyPopenProcs)
4756 {
4757 _PyPopenProcs = PyDict_New();
4758 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004759
Victor Stinnerd6f85422010-05-05 23:33:33 +00004760 if (_PyPopenProcs)
4761 {
4762 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4763 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004764
Victor Stinnerd6f85422010-05-05 23:33:33 +00004765 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4766 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004767
Victor Stinnerd6f85422010-05-05 23:33:33 +00004768 procObj = PyList_New(2);
4769 pidObj = PyLong_FromPid(pipe_pid);
4770 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004771
Victor Stinnerd6f85422010-05-05 23:33:33 +00004772 if (procObj && pidObj && intObj)
4773 {
4774 PyList_SetItem(procObj, 0, pidObj);
4775 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004776
Victor Stinnerd6f85422010-05-05 23:33:33 +00004777 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4778 if (fileObj[0])
4779 {
4780 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4781 fileObj[0],
4782 procObj);
4783 }
4784 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4785 if (fileObj[1])
4786 {
4787 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4788 fileObj[1],
4789 procObj);
4790 }
4791 if (file_count >= 3)
4792 {
4793 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4794 if (fileObj[2])
4795 {
4796 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4797 fileObj[2],
4798 procObj);
4799 }
4800 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004801
Victor Stinnerd6f85422010-05-05 23:33:33 +00004802 if (ins_rc[0] < 0 || !fileObj[0] ||
4803 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4804 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4805 {
4806 /* Something failed - remove any dictionary
4807 * entries that did make it.
4808 */
4809 if (!ins_rc[0] && fileObj[0])
4810 {
4811 PyDict_DelItem(_PyPopenProcs,
4812 fileObj[0]);
4813 }
4814 if (!ins_rc[1] && fileObj[1])
4815 {
4816 PyDict_DelItem(_PyPopenProcs,
4817 fileObj[1]);
4818 }
4819 if (!ins_rc[2] && fileObj[2])
4820 {
4821 PyDict_DelItem(_PyPopenProcs,
4822 fileObj[2]);
4823 }
4824 }
4825 }
Tim Peters11b23062003-04-23 02:39:17 +00004826
Victor Stinnerd6f85422010-05-05 23:33:33 +00004827 /*
4828 * Clean up our localized references for the dictionary keys
4829 * and value since PyDict_SetItem will Py_INCREF any copies
4830 * that got placed in the dictionary.
4831 */
4832 Py_XDECREF(procObj);
4833 Py_XDECREF(fileObj[0]);
4834 Py_XDECREF(fileObj[1]);
4835 Py_XDECREF(fileObj[2]);
4836 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004837
Victor Stinnerd6f85422010-05-05 23:33:33 +00004838 /* Child is launched. */
4839 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004840}
4841
4842/*
4843 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4844 * exit code for the child process and return as a result of the close.
4845 *
4846 * This function uses the _PyPopenProcs dictionary in order to map the
4847 * input file pointer to information about the process that was
4848 * originally created by the popen* call that created the file pointer.
4849 * The dictionary uses the file pointer as a key (with one entry
4850 * inserted for each file returned by the original popen* call) and a
4851 * single list object as the value for all files from a single call.
4852 * The list object contains the Win32 process handle at [0], and a file
4853 * count at [1], which is initialized to the total number of file
4854 * handles using that list.
4855 *
4856 * This function closes whichever handle it is passed, and decrements
4857 * the file count in the dictionary for the process handle pointed to
4858 * by this file. On the last close (when the file count reaches zero),
4859 * this function will wait for the child process and then return its
4860 * exit code as the result of the close() operation. This permits the
4861 * files to be closed in any order - it is always the close() of the
4862 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004863 *
4864 * NOTE: This function is currently called with the GIL released.
4865 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004866 */
4867
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004868static int _PyPclose(FILE *file)
4869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004870 int result;
4871 int exit_code;
4872 pid_t pipe_pid;
4873 PyObject *procObj, *pidObj, *intObj, *fileObj;
4874 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004875#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004876 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004877#endif
4878
Victor Stinnerd6f85422010-05-05 23:33:33 +00004879 /* Close the file handle first, to ensure it can't block the
4880 * child from exiting if it's the last handle.
4881 */
4882 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004883
4884#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004885 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004886#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004887 if (_PyPopenProcs)
4888 {
4889 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4890 (procObj = PyDict_GetItem(_PyPopenProcs,
4891 fileObj)) != NULL &&
4892 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4893 (intObj = PyList_GetItem(procObj,1)) != NULL)
4894 {
4895 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4896 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004897
Victor Stinnerd6f85422010-05-05 23:33:33 +00004898 if (file_count > 1)
4899 {
4900 /* Still other files referencing process */
4901 file_count--;
4902 PyList_SetItem(procObj,1,
4903 PyInt_FromLong((long) file_count));
4904 }
4905 else
4906 {
4907 /* Last file for this process */
4908 if (result != EOF &&
4909 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4910 {
4911 /* extract exit status */
4912 if (WIFEXITED(exit_code))
4913 {
4914 result = WEXITSTATUS(exit_code);
4915 }
4916 else
4917 {
4918 errno = EPIPE;
4919 result = -1;
4920 }
4921 }
4922 else
4923 {
4924 /* Indicate failure - this will cause the file object
4925 * to raise an I/O error and translate the last
4926 * error code from errno. We do have a problem with
4927 * last errors that overlap the normal errno table,
4928 * but that's a consistent problem with the file object.
4929 */
4930 result = -1;
4931 }
4932 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004933
Victor Stinnerd6f85422010-05-05 23:33:33 +00004934 /* Remove this file pointer from dictionary */
4935 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004936
Victor Stinnerd6f85422010-05-05 23:33:33 +00004937 if (PyDict_Size(_PyPopenProcs) == 0)
4938 {
4939 Py_DECREF(_PyPopenProcs);
4940 _PyPopenProcs = NULL;
4941 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004942
Victor Stinnerd6f85422010-05-05 23:33:33 +00004943 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004944
Victor Stinnerd6f85422010-05-05 23:33:33 +00004945 Py_XDECREF(fileObj);
4946 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004947
4948#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004949 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004950#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004951 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004952}
4953
4954#endif /* PYCC_??? */
4955
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004956#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004957
4958/*
4959 * Portable 'popen' replacement for Win32.
4960 *
4961 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4962 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004963 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004964 */
4965
4966#include <malloc.h>
4967#include <io.h>
4968#include <fcntl.h>
4969
4970/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4971#define POPEN_1 1
4972#define POPEN_2 2
4973#define POPEN_3 3
4974#define POPEN_4 4
4975
4976static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004977static int _PyPclose(FILE *file);
4978
4979/*
4980 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004981 * for use when retrieving the process exit code. See _PyPclose() below
4982 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004983 */
4984static PyObject *_PyPopenProcs = NULL;
4985
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004986
4987/* popen that works from a GUI.
4988 *
4989 * The result of this function is a pipe (file) connected to the
4990 * processes stdin or stdout, depending on the requested mode.
4991 */
4992
4993static PyObject *
4994posix_popen(PyObject *self, PyObject *args)
4995{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004996 PyObject *f;
4997 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004998
Victor Stinnerd6f85422010-05-05 23:33:33 +00004999 char *cmdstring;
5000 char *mode = "r";
5001 int bufsize = -1;
5002 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5003 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005004
Victor Stinnerd6f85422010-05-05 23:33:33 +00005005 if (*mode == 'r')
5006 tm = _O_RDONLY;
5007 else if (*mode != 'w') {
5008 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5009 return NULL;
5010 } else
5011 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005012
Victor Stinnerd6f85422010-05-05 23:33:33 +00005013 if (bufsize != -1) {
5014 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5015 return NULL;
5016 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005017
Victor Stinnerd6f85422010-05-05 23:33:33 +00005018 if (*(mode+1) == 't')
5019 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5020 else if (*(mode+1) == 'b')
5021 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5022 else
5023 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005024
Victor Stinnerd6f85422010-05-05 23:33:33 +00005025 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005026}
5027
5028/* Variation on win32pipe.popen
5029 *
5030 * The result of this function is a pipe (file) connected to the
5031 * process's stdin, and a pipe connected to the process's stdout.
5032 */
5033
5034static PyObject *
5035win32_popen2(PyObject *self, PyObject *args)
5036{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005037 PyObject *f;
5038 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005039
Victor Stinnerd6f85422010-05-05 23:33:33 +00005040 char *cmdstring;
5041 char *mode = "t";
5042 int bufsize = -1;
5043 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5044 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005045
Victor Stinnerd6f85422010-05-05 23:33:33 +00005046 if (*mode == 't')
5047 tm = _O_TEXT;
5048 else if (*mode != 'b') {
5049 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5050 return NULL;
5051 } else
5052 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005053
Victor Stinnerd6f85422010-05-05 23:33:33 +00005054 if (bufsize != -1) {
5055 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5056 return NULL;
5057 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005058
Victor Stinnerd6f85422010-05-05 23:33:33 +00005059 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005060
Victor Stinnerd6f85422010-05-05 23:33:33 +00005061 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005062}
5063
5064/*
5065 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005066 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005067 * The result of this function is 3 pipes - the process's stdin,
5068 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005069 */
5070
5071static PyObject *
5072win32_popen3(PyObject *self, PyObject *args)
5073{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005074 PyObject *f;
5075 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005076
Victor Stinnerd6f85422010-05-05 23:33:33 +00005077 char *cmdstring;
5078 char *mode = "t";
5079 int bufsize = -1;
5080 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5081 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005082
Victor Stinnerd6f85422010-05-05 23:33:33 +00005083 if (*mode == 't')
5084 tm = _O_TEXT;
5085 else if (*mode != 'b') {
5086 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5087 return NULL;
5088 } else
5089 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005090
Victor Stinnerd6f85422010-05-05 23:33:33 +00005091 if (bufsize != -1) {
5092 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5093 return NULL;
5094 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005095
Victor Stinnerd6f85422010-05-05 23:33:33 +00005096 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005097
Victor Stinnerd6f85422010-05-05 23:33:33 +00005098 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005099}
5100
5101/*
5102 * Variation on win32pipe.popen
5103 *
Tim Peters5aa91602002-01-30 05:46:57 +00005104 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005105 * and stdout+stderr combined as a single pipe.
5106 */
5107
5108static PyObject *
5109win32_popen4(PyObject *self, PyObject *args)
5110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005111 PyObject *f;
5112 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005113
Victor Stinnerd6f85422010-05-05 23:33:33 +00005114 char *cmdstring;
5115 char *mode = "t";
5116 int bufsize = -1;
5117 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5118 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005119
Victor Stinnerd6f85422010-05-05 23:33:33 +00005120 if (*mode == 't')
5121 tm = _O_TEXT;
5122 else if (*mode != 'b') {
5123 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5124 return NULL;
5125 } else
5126 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005127
Victor Stinnerd6f85422010-05-05 23:33:33 +00005128 if (bufsize != -1) {
5129 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5130 return NULL;
5131 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005132
Victor Stinnerd6f85422010-05-05 23:33:33 +00005133 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005134
Victor Stinnerd6f85422010-05-05 23:33:33 +00005135 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005136}
5137
Mark Hammond08501372001-01-31 07:30:29 +00005138static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005139_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005140 HANDLE hStdin,
5141 HANDLE hStdout,
5142 HANDLE hStderr,
5143 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005144{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005145 PROCESS_INFORMATION piProcInfo;
5146 STARTUPINFO siStartInfo;
5147 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5148 char *s1,*s2, *s3 = " /c ";
5149 const char *szConsoleSpawn = "w9xpopen.exe";
5150 int i;
5151 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005152
Victor Stinnerd6f85422010-05-05 23:33:33 +00005153 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5154 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005155
Victor Stinnerd6f85422010-05-05 23:33:33 +00005156 s1 = (char *)alloca(i);
5157 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5158 /* x < i, so x fits into an integer */
5159 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005160
Victor Stinnerd6f85422010-05-05 23:33:33 +00005161 /* Explicitly check if we are using COMMAND.COM. If we are
5162 * then use the w9xpopen hack.
5163 */
5164 comshell = s1 + x;
5165 while (comshell >= s1 && *comshell != '\\')
5166 --comshell;
5167 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005168
Victor Stinnerd6f85422010-05-05 23:33:33 +00005169 if (GetVersion() < 0x80000000 &&
5170 _stricmp(comshell, "command.com") != 0) {
5171 /* NT/2000 and not using command.com. */
5172 x = i + strlen(s3) + strlen(cmdstring) + 1;
5173 s2 = (char *)alloca(x);
5174 ZeroMemory(s2, x);
5175 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5176 }
5177 else {
5178 /*
5179 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5180 * the workaround listed in KB: Q150956
5181 */
5182 char modulepath[_MAX_PATH];
5183 struct stat statinfo;
5184 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5185 for (x = i = 0; modulepath[i]; i++)
5186 if (modulepath[i] == SEP)
5187 x = i+1;
5188 modulepath[x] = '\0';
5189 /* Create the full-name to w9xpopen, so we can test it exists */
5190 strncat(modulepath,
5191 szConsoleSpawn,
5192 (sizeof(modulepath)/sizeof(modulepath[0]))
5193 -strlen(modulepath));
5194 if (stat(modulepath, &statinfo) != 0) {
5195 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5196 /* Eeek - file-not-found - possibly an embedding
5197 situation - see if we can locate it in sys.prefix
5198 */
5199 strncpy(modulepath,
5200 Py_GetExecPrefix(),
5201 mplen);
5202 modulepath[mplen-1] = '\0';
5203 if (modulepath[strlen(modulepath)-1] != '\\')
5204 strcat(modulepath, "\\");
5205 strncat(modulepath,
5206 szConsoleSpawn,
5207 mplen-strlen(modulepath));
5208 /* No where else to look - raise an easily identifiable
5209 error, rather than leaving Windows to report
5210 "file not found" - as the user is probably blissfully
5211 unaware this shim EXE is used, and it will confuse them.
5212 (well, it confused me for a while ;-)
5213 */
5214 if (stat(modulepath, &statinfo) != 0) {
5215 PyErr_Format(PyExc_RuntimeError,
5216 "Can not locate '%s' which is needed "
5217 "for popen to work with your shell "
5218 "or platform.",
5219 szConsoleSpawn);
5220 return FALSE;
5221 }
5222 }
5223 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5224 strlen(modulepath) +
5225 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005226
Victor Stinnerd6f85422010-05-05 23:33:33 +00005227 s2 = (char *)alloca(x);
5228 ZeroMemory(s2, x);
5229 /* To maintain correct argument passing semantics,
5230 we pass the command-line as it stands, and allow
5231 quoting to be applied. w9xpopen.exe will then
5232 use its argv vector, and re-quote the necessary
5233 args for the ultimate child process.
5234 */
5235 PyOS_snprintf(
5236 s2, x,
5237 "\"%s\" %s%s%s",
5238 modulepath,
5239 s1,
5240 s3,
5241 cmdstring);
5242 /* Not passing CREATE_NEW_CONSOLE has been known to
5243 cause random failures on win9x. Specifically a
5244 dialog:
5245 "Your program accessed mem currently in use at xxx"
5246 and a hopeful warning about the stability of your
5247 system.
5248 Cost is Ctrl+C won't kill children, but anyone
5249 who cares can have a go!
5250 */
5251 dwProcessFlags |= CREATE_NEW_CONSOLE;
5252 }
5253 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005254
Victor Stinnerd6f85422010-05-05 23:33:33 +00005255 /* Could be an else here to try cmd.exe / command.com in the path
5256 Now we'll just error out.. */
5257 else {
5258 PyErr_SetString(PyExc_RuntimeError,
5259 "Cannot locate a COMSPEC environment variable to "
5260 "use as the shell");
5261 return FALSE;
5262 }
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Victor Stinnerd6f85422010-05-05 23:33:33 +00005264 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5265 siStartInfo.cb = sizeof(STARTUPINFO);
5266 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5267 siStartInfo.hStdInput = hStdin;
5268 siStartInfo.hStdOutput = hStdout;
5269 siStartInfo.hStdError = hStderr;
5270 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005271
Victor Stinnerd6f85422010-05-05 23:33:33 +00005272 if (CreateProcess(NULL,
5273 s2,
5274 NULL,
5275 NULL,
5276 TRUE,
5277 dwProcessFlags,
5278 NULL,
5279 NULL,
5280 &siStartInfo,
5281 &piProcInfo) ) {
5282 /* Close the handles now so anyone waiting is woken. */
5283 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005284
Victor Stinnerd6f85422010-05-05 23:33:33 +00005285 /* Return process handle */
5286 *hProcess = piProcInfo.hProcess;
5287 return TRUE;
5288 }
5289 win32_error("CreateProcess", s2);
5290 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005291}
5292
5293/* The following code is based off of KB: Q190351 */
5294
5295static PyObject *
5296_PyPopen(char *cmdstring, int mode, int n)
5297{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005298 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5299 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5300 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005301
Victor Stinnerd6f85422010-05-05 23:33:33 +00005302 SECURITY_ATTRIBUTES saAttr;
5303 BOOL fSuccess;
5304 int fd1, fd2, fd3;
5305 FILE *f1, *f2, *f3;
5306 long file_count;
5307 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005308
Victor Stinnerd6f85422010-05-05 23:33:33 +00005309 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5310 saAttr.bInheritHandle = TRUE;
5311 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005312
Victor Stinnerd6f85422010-05-05 23:33:33 +00005313 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5314 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005315
Victor Stinnerd6f85422010-05-05 23:33:33 +00005316 /* Create new output read handle and the input write handle. Set
5317 * the inheritance properties to FALSE. Otherwise, the child inherits
5318 * these handles; resulting in non-closeable handles to the pipes
5319 * being created. */
5320 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5321 GetCurrentProcess(), &hChildStdinWrDup, 0,
5322 FALSE,
5323 DUPLICATE_SAME_ACCESS);
5324 if (!fSuccess)
5325 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005326
Victor Stinnerd6f85422010-05-05 23:33:33 +00005327 /* Close the inheritable version of ChildStdin
5328 that we're using. */
5329 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005330
Victor Stinnerd6f85422010-05-05 23:33:33 +00005331 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5332 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005333
Victor Stinnerd6f85422010-05-05 23:33:33 +00005334 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5335 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5336 FALSE, DUPLICATE_SAME_ACCESS);
5337 if (!fSuccess)
5338 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005339
Victor Stinnerd6f85422010-05-05 23:33:33 +00005340 /* Close the inheritable version of ChildStdout
5341 that we're using. */
5342 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005343
Victor Stinnerd6f85422010-05-05 23:33:33 +00005344 if (n != POPEN_4) {
5345 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5346 return win32_error("CreatePipe", NULL);
5347 fSuccess = DuplicateHandle(GetCurrentProcess(),
5348 hChildStderrRd,
5349 GetCurrentProcess(),
5350 &hChildStderrRdDup, 0,
5351 FALSE, DUPLICATE_SAME_ACCESS);
5352 if (!fSuccess)
5353 return win32_error("DuplicateHandle", NULL);
5354 /* Close the inheritable version of ChildStdErr that we're using. */
5355 CloseHandle(hChildStderrRd);
5356 }
Tim Peters5aa91602002-01-30 05:46:57 +00005357
Victor Stinnerd6f85422010-05-05 23:33:33 +00005358 switch (n) {
5359 case POPEN_1:
5360 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5361 case _O_WRONLY | _O_TEXT:
5362 /* Case for writing to child Stdin in text mode. */
5363 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5364 f1 = _fdopen(fd1, "w");
5365 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5366 PyFile_SetBufSize(f, 0);
5367 /* We don't care about these pipes anymore, so close them. */
5368 CloseHandle(hChildStdoutRdDup);
5369 CloseHandle(hChildStderrRdDup);
5370 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005371
Victor Stinnerd6f85422010-05-05 23:33:33 +00005372 case _O_RDONLY | _O_TEXT:
5373 /* Case for reading from child Stdout in text mode. */
5374 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5375 f1 = _fdopen(fd1, "r");
5376 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5377 PyFile_SetBufSize(f, 0);
5378 /* We don't care about these pipes anymore, so close them. */
5379 CloseHandle(hChildStdinWrDup);
5380 CloseHandle(hChildStderrRdDup);
5381 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005382
Victor Stinnerd6f85422010-05-05 23:33:33 +00005383 case _O_RDONLY | _O_BINARY:
5384 /* Case for readinig from child Stdout in binary mode. */
5385 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5386 f1 = _fdopen(fd1, "rb");
5387 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5388 PyFile_SetBufSize(f, 0);
5389 /* We don't care about these pipes anymore, so close them. */
5390 CloseHandle(hChildStdinWrDup);
5391 CloseHandle(hChildStderrRdDup);
5392 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005393
Victor Stinnerd6f85422010-05-05 23:33:33 +00005394 case _O_WRONLY | _O_BINARY:
5395 /* Case for writing to child Stdin in binary mode. */
5396 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5397 f1 = _fdopen(fd1, "wb");
5398 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5399 PyFile_SetBufSize(f, 0);
5400 /* We don't care about these pipes anymore, so close them. */
5401 CloseHandle(hChildStdoutRdDup);
5402 CloseHandle(hChildStderrRdDup);
5403 break;
5404 }
5405 file_count = 1;
5406 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005407
Victor Stinnerd6f85422010-05-05 23:33:33 +00005408 case POPEN_2:
5409 case POPEN_4:
5410 {
5411 char *m1, *m2;
5412 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005413
Victor Stinnerd6f85422010-05-05 23:33:33 +00005414 if (mode & _O_TEXT) {
5415 m1 = "r";
5416 m2 = "w";
5417 } else {
5418 m1 = "rb";
5419 m2 = "wb";
5420 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005421
Victor Stinnerd6f85422010-05-05 23:33:33 +00005422 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5423 f1 = _fdopen(fd1, m2);
5424 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5425 f2 = _fdopen(fd2, m1);
5426 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5427 PyFile_SetBufSize(p1, 0);
5428 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5429 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005430
Victor Stinnerd6f85422010-05-05 23:33:33 +00005431 if (n != 4)
5432 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005433
Victor Stinnerd6f85422010-05-05 23:33:33 +00005434 f = PyTuple_Pack(2,p1,p2);
5435 Py_XDECREF(p1);
5436 Py_XDECREF(p2);
5437 file_count = 2;
5438 break;
5439 }
Tim Peters5aa91602002-01-30 05:46:57 +00005440
Victor Stinnerd6f85422010-05-05 23:33:33 +00005441 case POPEN_3:
5442 {
5443 char *m1, *m2;
5444 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005445
Victor Stinnerd6f85422010-05-05 23:33:33 +00005446 if (mode & _O_TEXT) {
5447 m1 = "r";
5448 m2 = "w";
5449 } else {
5450 m1 = "rb";
5451 m2 = "wb";
5452 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005453
Victor Stinnerd6f85422010-05-05 23:33:33 +00005454 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5455 f1 = _fdopen(fd1, m2);
5456 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5457 f2 = _fdopen(fd2, m1);
5458 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5459 f3 = _fdopen(fd3, m1);
5460 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5461 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5462 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5463 PyFile_SetBufSize(p1, 0);
5464 PyFile_SetBufSize(p2, 0);
5465 PyFile_SetBufSize(p3, 0);
5466 f = PyTuple_Pack(3,p1,p2,p3);
5467 Py_XDECREF(p1);
5468 Py_XDECREF(p2);
5469 Py_XDECREF(p3);
5470 file_count = 3;
5471 break;
5472 }
5473 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005474
Victor Stinnerd6f85422010-05-05 23:33:33 +00005475 if (n == POPEN_4) {
5476 if (!_PyPopenCreateProcess(cmdstring,
5477 hChildStdinRd,
5478 hChildStdoutWr,
5479 hChildStdoutWr,
5480 &hProcess))
5481 return NULL;
5482 }
5483 else {
5484 if (!_PyPopenCreateProcess(cmdstring,
5485 hChildStdinRd,
5486 hChildStdoutWr,
5487 hChildStderrWr,
5488 &hProcess))
5489 return NULL;
5490 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005491
Victor Stinnerd6f85422010-05-05 23:33:33 +00005492 /*
5493 * Insert the files we've created into the process dictionary
5494 * all referencing the list with the process handle and the
5495 * initial number of files (see description below in _PyPclose).
5496 * Since if _PyPclose later tried to wait on a process when all
5497 * handles weren't closed, it could create a deadlock with the
5498 * child, we spend some energy here to try to ensure that we
5499 * either insert all file handles into the dictionary or none
5500 * at all. It's a little clumsy with the various popen modes
5501 * and variable number of files involved.
5502 */
5503 if (!_PyPopenProcs) {
5504 _PyPopenProcs = PyDict_New();
5505 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005506
Victor Stinnerd6f85422010-05-05 23:33:33 +00005507 if (_PyPopenProcs) {
5508 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5509 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005510
Victor Stinnerd6f85422010-05-05 23:33:33 +00005511 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5512 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005513
Victor Stinnerd6f85422010-05-05 23:33:33 +00005514 procObj = PyList_New(2);
5515 hProcessObj = PyLong_FromVoidPtr(hProcess);
5516 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005517
Victor Stinnerd6f85422010-05-05 23:33:33 +00005518 if (procObj && hProcessObj && intObj) {
5519 PyList_SetItem(procObj,0,hProcessObj);
5520 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005521
Victor Stinnerd6f85422010-05-05 23:33:33 +00005522 fileObj[0] = PyLong_FromVoidPtr(f1);
5523 if (fileObj[0]) {
5524 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5525 fileObj[0],
5526 procObj);
5527 }
5528 if (file_count >= 2) {
5529 fileObj[1] = PyLong_FromVoidPtr(f2);
5530 if (fileObj[1]) {
5531 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5532 fileObj[1],
5533 procObj);
5534 }
5535 }
5536 if (file_count >= 3) {
5537 fileObj[2] = PyLong_FromVoidPtr(f3);
5538 if (fileObj[2]) {
5539 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5540 fileObj[2],
5541 procObj);
5542 }
5543 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005544
Victor Stinnerd6f85422010-05-05 23:33:33 +00005545 if (ins_rc[0] < 0 || !fileObj[0] ||
5546 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5547 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5548 /* Something failed - remove any dictionary
5549 * entries that did make it.
5550 */
5551 if (!ins_rc[0] && fileObj[0]) {
5552 PyDict_DelItem(_PyPopenProcs,
5553 fileObj[0]);
5554 }
5555 if (!ins_rc[1] && fileObj[1]) {
5556 PyDict_DelItem(_PyPopenProcs,
5557 fileObj[1]);
5558 }
5559 if (!ins_rc[2] && fileObj[2]) {
5560 PyDict_DelItem(_PyPopenProcs,
5561 fileObj[2]);
5562 }
5563 }
5564 }
Tim Peters5aa91602002-01-30 05:46:57 +00005565
Victor Stinnerd6f85422010-05-05 23:33:33 +00005566 /*
5567 * Clean up our localized references for the dictionary keys
5568 * and value since PyDict_SetItem will Py_INCREF any copies
5569 * that got placed in the dictionary.
5570 */
5571 Py_XDECREF(procObj);
5572 Py_XDECREF(fileObj[0]);
5573 Py_XDECREF(fileObj[1]);
5574 Py_XDECREF(fileObj[2]);
5575 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005576
Victor Stinnerd6f85422010-05-05 23:33:33 +00005577 /* Child is launched. Close the parents copy of those pipe
5578 * handles that only the child should have open. You need to
5579 * make sure that no handles to the write end of the output pipe
5580 * are maintained in this process or else the pipe will not close
5581 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005582
Victor Stinnerd6f85422010-05-05 23:33:33 +00005583 if (!CloseHandle(hChildStdinRd))
5584 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005585
Victor Stinnerd6f85422010-05-05 23:33:33 +00005586 if (!CloseHandle(hChildStdoutWr))
5587 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005588
Victor Stinnerd6f85422010-05-05 23:33:33 +00005589 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5590 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005591
Victor Stinnerd6f85422010-05-05 23:33:33 +00005592 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005593}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005594
5595/*
5596 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5597 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005598 *
5599 * This function uses the _PyPopenProcs dictionary in order to map the
5600 * input file pointer to information about the process that was
5601 * originally created by the popen* call that created the file pointer.
5602 * The dictionary uses the file pointer as a key (with one entry
5603 * inserted for each file returned by the original popen* call) and a
5604 * single list object as the value for all files from a single call.
5605 * The list object contains the Win32 process handle at [0], and a file
5606 * count at [1], which is initialized to the total number of file
5607 * handles using that list.
5608 *
5609 * This function closes whichever handle it is passed, and decrements
5610 * the file count in the dictionary for the process handle pointed to
5611 * by this file. On the last close (when the file count reaches zero),
5612 * this function will wait for the child process and then return its
5613 * exit code as the result of the close() operation. This permits the
5614 * files to be closed in any order - it is always the close() of the
5615 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005616 *
5617 * NOTE: This function is currently called with the GIL released.
5618 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005619 */
Tim Peters736aa322000-09-01 06:51:24 +00005620
Fredrik Lundh56055a42000-07-23 19:47:12 +00005621static int _PyPclose(FILE *file)
5622{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005623 int result;
5624 DWORD exit_code;
5625 HANDLE hProcess;
5626 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5627 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005628#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005629 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005630#endif
5631
Victor Stinnerd6f85422010-05-05 23:33:33 +00005632 /* Close the file handle first, to ensure it can't block the
5633 * child from exiting if it's the last handle.
5634 */
5635 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005636#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005637 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005638#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005639 if (_PyPopenProcs) {
5640 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5641 (procObj = PyDict_GetItem(_PyPopenProcs,
5642 fileObj)) != NULL &&
5643 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5644 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005645
Victor Stinnerd6f85422010-05-05 23:33:33 +00005646 hProcess = PyLong_AsVoidPtr(hProcessObj);
5647 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005648
Victor Stinnerd6f85422010-05-05 23:33:33 +00005649 if (file_count > 1) {
5650 /* Still other files referencing process */
5651 file_count--;
5652 PyList_SetItem(procObj,1,
5653 PyInt_FromLong(file_count));
5654 } else {
5655 /* Last file for this process */
5656 if (result != EOF &&
5657 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5658 GetExitCodeProcess(hProcess, &exit_code)) {
5659 /* Possible truncation here in 16-bit environments, but
5660 * real exit codes are just the lower byte in any event.
5661 */
5662 result = exit_code;
5663 } else {
5664 /* Indicate failure - this will cause the file object
5665 * to raise an I/O error and translate the last Win32
5666 * error code from errno. We do have a problem with
5667 * last errors that overlap the normal errno table,
5668 * but that's a consistent problem with the file object.
5669 */
5670 if (result != EOF) {
5671 /* If the error wasn't from the fclose(), then
5672 * set errno for the file object error handling.
5673 */
5674 errno = GetLastError();
5675 }
5676 result = -1;
5677 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005678
Victor Stinnerd6f85422010-05-05 23:33:33 +00005679 /* Free up the native handle at this point */
5680 CloseHandle(hProcess);
5681 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005682
Victor Stinnerd6f85422010-05-05 23:33:33 +00005683 /* Remove this file pointer from dictionary */
5684 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005685
Victor Stinnerd6f85422010-05-05 23:33:33 +00005686 if (PyDict_Size(_PyPopenProcs) == 0) {
5687 Py_DECREF(_PyPopenProcs);
5688 _PyPopenProcs = NULL;
5689 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005690
Victor Stinnerd6f85422010-05-05 23:33:33 +00005691 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005692
Victor Stinnerd6f85422010-05-05 23:33:33 +00005693 Py_XDECREF(fileObj);
5694 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005695
Tim Peters736aa322000-09-01 06:51:24 +00005696#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005697 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005698#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005699 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005700}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005701
5702#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005704posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005705{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005706 char *name;
5707 char *mode = "r";
5708 int bufsize = -1;
5709 FILE *fp;
5710 PyObject *f;
5711 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5712 return NULL;
5713 /* Strip mode of binary or text modifiers */
5714 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5715 mode = "r";
5716 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5717 mode = "w";
5718 Py_BEGIN_ALLOW_THREADS
5719 fp = popen(name, mode);
5720 Py_END_ALLOW_THREADS
5721 if (fp == NULL)
5722 return posix_error();
5723 f = PyFile_FromFile(fp, name, mode, pclose);
5724 if (f != NULL)
5725 PyFile_SetBufSize(f, bufsize);
5726 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005727}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005728
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005729#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005730#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005732
Guido van Rossumb6775db1994-08-01 11:34:53 +00005733#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Set the current process's user id.");
5737
Barry Warsaw53699e91996-12-10 23:23:01 +00005738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005739posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005740{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005741 long uid_arg;
5742 uid_t uid;
5743 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5744 return NULL;
5745 uid = uid_arg;
5746 if (uid != uid_arg) {
5747 PyErr_SetString(PyExc_OverflowError, "user id too big");
5748 return NULL;
5749 }
5750 if (setuid(uid) < 0)
5751 return posix_error();
5752 Py_INCREF(Py_None);
5753 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005754}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005755#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005757
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005758#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005760"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005761Set the current process's effective user id.");
5762
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005763static PyObject *
5764posix_seteuid (PyObject *self, PyObject *args)
5765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005766 long euid_arg;
5767 uid_t euid;
5768 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5769 return NULL;
5770 euid = euid_arg;
5771 if (euid != euid_arg) {
5772 PyErr_SetString(PyExc_OverflowError, "user id too big");
5773 return NULL;
5774 }
5775 if (seteuid(euid) < 0) {
5776 return posix_error();
5777 } else {
5778 Py_INCREF(Py_None);
5779 return Py_None;
5780 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005781}
5782#endif /* HAVE_SETEUID */
5783
5784#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005785PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005786"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787Set the current process's effective group id.");
5788
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005789static PyObject *
5790posix_setegid (PyObject *self, PyObject *args)
5791{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005792 long egid_arg;
5793 gid_t egid;
5794 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5795 return NULL;
5796 egid = egid_arg;
5797 if (egid != egid_arg) {
5798 PyErr_SetString(PyExc_OverflowError, "group id too big");
5799 return NULL;
5800 }
5801 if (setegid(egid) < 0) {
5802 return posix_error();
5803 } else {
5804 Py_INCREF(Py_None);
5805 return Py_None;
5806 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005807}
5808#endif /* HAVE_SETEGID */
5809
5810#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005811PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005812"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005813Set the current process's real and effective user ids.");
5814
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005815static PyObject *
5816posix_setreuid (PyObject *self, PyObject *args)
5817{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005818 long ruid_arg, euid_arg;
5819 uid_t ruid, euid;
5820 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5821 return NULL;
5822 if (ruid_arg == -1)
5823 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5824 else
5825 ruid = ruid_arg; /* otherwise, assign from our long */
5826 if (euid_arg == -1)
5827 euid = (uid_t)-1;
5828 else
5829 euid = euid_arg;
5830 if ((euid_arg != -1 && euid != euid_arg) ||
5831 (ruid_arg != -1 && ruid != ruid_arg)) {
5832 PyErr_SetString(PyExc_OverflowError, "user id too big");
5833 return NULL;
5834 }
5835 if (setreuid(ruid, euid) < 0) {
5836 return posix_error();
5837 } else {
5838 Py_INCREF(Py_None);
5839 return Py_None;
5840 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005841}
5842#endif /* HAVE_SETREUID */
5843
5844#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005845PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005846"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847Set the current process's real and effective group ids.");
5848
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005849static PyObject *
5850posix_setregid (PyObject *self, PyObject *args)
5851{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005852 long rgid_arg, egid_arg;
5853 gid_t rgid, egid;
5854 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5855 return NULL;
5856 if (rgid_arg == -1)
5857 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5858 else
5859 rgid = rgid_arg; /* otherwise, assign from our long */
5860 if (egid_arg == -1)
5861 egid = (gid_t)-1;
5862 else
5863 egid = egid_arg;
5864 if ((egid_arg != -1 && egid != egid_arg) ||
5865 (rgid_arg != -1 && rgid != rgid_arg)) {
5866 PyErr_SetString(PyExc_OverflowError, "group id too big");
5867 return NULL;
5868 }
5869 if (setregid(rgid, egid) < 0) {
5870 return posix_error();
5871 } else {
5872 Py_INCREF(Py_None);
5873 return Py_None;
5874 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005875}
5876#endif /* HAVE_SETREGID */
5877
Guido van Rossumb6775db1994-08-01 11:34:53 +00005878#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005880"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005881Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005882
Barry Warsaw53699e91996-12-10 23:23:01 +00005883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005884posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005885{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005886 long gid_arg;
5887 gid_t gid;
5888 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5889 return NULL;
5890 gid = gid_arg;
5891 if (gid != gid_arg) {
5892 PyErr_SetString(PyExc_OverflowError, "group id too big");
5893 return NULL;
5894 }
5895 if (setgid(gid) < 0)
5896 return posix_error();
5897 Py_INCREF(Py_None);
5898 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005899}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005900#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005901
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005902#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005903PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005904"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005905Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005906
5907static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005908posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005909{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005910 int i, len;
5911 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005912
Victor Stinnerd6f85422010-05-05 23:33:33 +00005913 if (!PySequence_Check(groups)) {
5914 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5915 return NULL;
5916 }
5917 len = PySequence_Size(groups);
5918 if (len > MAX_GROUPS) {
5919 PyErr_SetString(PyExc_ValueError, "too many groups");
5920 return NULL;
5921 }
5922 for(i = 0; i < len; i++) {
5923 PyObject *elem;
5924 elem = PySequence_GetItem(groups, i);
5925 if (!elem)
5926 return NULL;
5927 if (!PyInt_Check(elem)) {
5928 if (!PyLong_Check(elem)) {
5929 PyErr_SetString(PyExc_TypeError,
5930 "groups must be integers");
5931 Py_DECREF(elem);
5932 return NULL;
5933 } else {
5934 unsigned long x = PyLong_AsUnsignedLong(elem);
5935 if (PyErr_Occurred()) {
5936 PyErr_SetString(PyExc_TypeError,
5937 "group id too big");
5938 Py_DECREF(elem);
5939 return NULL;
5940 }
5941 grouplist[i] = x;
5942 /* read back to see if it fits in gid_t */
5943 if (grouplist[i] != x) {
5944 PyErr_SetString(PyExc_TypeError,
5945 "group id too big");
5946 Py_DECREF(elem);
5947 return NULL;
5948 }
5949 }
5950 } else {
5951 long x = PyInt_AsLong(elem);
5952 grouplist[i] = x;
5953 if (grouplist[i] != x) {
5954 PyErr_SetString(PyExc_TypeError,
5955 "group id too big");
5956 Py_DECREF(elem);
5957 return NULL;
5958 }
5959 }
5960 Py_DECREF(elem);
5961 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005962
Victor Stinnerd6f85422010-05-05 23:33:33 +00005963 if (setgroups(len, grouplist) < 0)
5964 return posix_error();
5965 Py_INCREF(Py_None);
5966 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005967}
5968#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005969
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005970#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005971static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005972wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005973{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005974 PyObject *result;
5975 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005976
Victor Stinnerd6f85422010-05-05 23:33:33 +00005977 if (pid == -1)
5978 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005979
Victor Stinnerd6f85422010-05-05 23:33:33 +00005980 if (struct_rusage == NULL) {
5981 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5982 if (m == NULL)
5983 return NULL;
5984 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5985 Py_DECREF(m);
5986 if (struct_rusage == NULL)
5987 return NULL;
5988 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005989
Victor Stinnerd6f85422010-05-05 23:33:33 +00005990 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5991 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5992 if (!result)
5993 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005994
5995#ifndef doubletime
5996#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5997#endif
5998
Victor Stinnerd6f85422010-05-05 23:33:33 +00005999 PyStructSequence_SET_ITEM(result, 0,
6000 PyFloat_FromDouble(doubletime(ru->ru_utime)));
6001 PyStructSequence_SET_ITEM(result, 1,
6002 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006003#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006004 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6005 SET_INT(result, 2, ru->ru_maxrss);
6006 SET_INT(result, 3, ru->ru_ixrss);
6007 SET_INT(result, 4, ru->ru_idrss);
6008 SET_INT(result, 5, ru->ru_isrss);
6009 SET_INT(result, 6, ru->ru_minflt);
6010 SET_INT(result, 7, ru->ru_majflt);
6011 SET_INT(result, 8, ru->ru_nswap);
6012 SET_INT(result, 9, ru->ru_inblock);
6013 SET_INT(result, 10, ru->ru_oublock);
6014 SET_INT(result, 11, ru->ru_msgsnd);
6015 SET_INT(result, 12, ru->ru_msgrcv);
6016 SET_INT(result, 13, ru->ru_nsignals);
6017 SET_INT(result, 14, ru->ru_nvcsw);
6018 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006019#undef SET_INT
6020
Victor Stinnerd6f85422010-05-05 23:33:33 +00006021 if (PyErr_Occurred()) {
6022 Py_DECREF(result);
6023 return NULL;
6024 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006025
Victor Stinnerd6f85422010-05-05 23:33:33 +00006026 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006027}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006028#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006029
6030#ifdef HAVE_WAIT3
6031PyDoc_STRVAR(posix_wait3__doc__,
6032"wait3(options) -> (pid, status, rusage)\n\n\
6033Wait for completion of a child process.");
6034
6035static PyObject *
6036posix_wait3(PyObject *self, PyObject *args)
6037{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006038 pid_t pid;
6039 int options;
6040 struct rusage ru;
6041 WAIT_TYPE status;
6042 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006043
Victor Stinnerd6f85422010-05-05 23:33:33 +00006044 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6045 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006046
Victor Stinnerd6f85422010-05-05 23:33:33 +00006047 Py_BEGIN_ALLOW_THREADS
6048 pid = wait3(&status, options, &ru);
6049 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006050
Victor Stinnerd6f85422010-05-05 23:33:33 +00006051 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006052}
6053#endif /* HAVE_WAIT3 */
6054
6055#ifdef HAVE_WAIT4
6056PyDoc_STRVAR(posix_wait4__doc__,
6057"wait4(pid, options) -> (pid, status, rusage)\n\n\
6058Wait for completion of a given child process.");
6059
6060static PyObject *
6061posix_wait4(PyObject *self, PyObject *args)
6062{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006063 pid_t pid;
6064 int options;
6065 struct rusage ru;
6066 WAIT_TYPE status;
6067 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006068
Victor Stinnerd6f85422010-05-05 23:33:33 +00006069 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6070 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006071
Victor Stinnerd6f85422010-05-05 23:33:33 +00006072 Py_BEGIN_ALLOW_THREADS
6073 pid = wait4(pid, &status, options, &ru);
6074 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006075
Victor Stinnerd6f85422010-05-05 23:33:33 +00006076 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006077}
6078#endif /* HAVE_WAIT4 */
6079
Guido van Rossumb6775db1994-08-01 11:34:53 +00006080#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006082"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006083Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006084
Barry Warsaw53699e91996-12-10 23:23:01 +00006085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006086posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006087{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006088 pid_t pid;
6089 int options;
6090 WAIT_TYPE status;
6091 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006092
Victor Stinnerd6f85422010-05-05 23:33:33 +00006093 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6094 return NULL;
6095 Py_BEGIN_ALLOW_THREADS
6096 pid = waitpid(pid, &status, options);
6097 Py_END_ALLOW_THREADS
6098 if (pid == -1)
6099 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006100
Victor Stinnerd6f85422010-05-05 23:33:33 +00006101 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006102}
6103
Tim Petersab034fa2002-02-01 11:27:43 +00006104#elif defined(HAVE_CWAIT)
6105
6106/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006108"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006109"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006110
6111static PyObject *
6112posix_waitpid(PyObject *self, PyObject *args)
6113{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006114 Py_intptr_t pid;
6115 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006116
Victor Stinnerd6f85422010-05-05 23:33:33 +00006117 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6118 return NULL;
6119 Py_BEGIN_ALLOW_THREADS
6120 pid = _cwait(&status, pid, options);
6121 Py_END_ALLOW_THREADS
6122 if (pid == -1)
6123 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006124
Victor Stinnerd6f85422010-05-05 23:33:33 +00006125 /* shift the status left a byte so this is more like the POSIX waitpid */
6126 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006127}
6128#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006129
Guido van Rossumad0ee831995-03-01 10:34:45 +00006130#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006132"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Barry Warsaw53699e91996-12-10 23:23:01 +00006135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006136posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006137{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006138 pid_t pid;
6139 WAIT_TYPE status;
6140 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006141
Victor Stinnerd6f85422010-05-05 23:33:33 +00006142 Py_BEGIN_ALLOW_THREADS
6143 pid = wait(&status);
6144 Py_END_ALLOW_THREADS
6145 if (pid == -1)
6146 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006147
Victor Stinnerd6f85422010-05-05 23:33:33 +00006148 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006149}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006150#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006153PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006154"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006155Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006156
Barry Warsaw53699e91996-12-10 23:23:01 +00006157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006158posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006159{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006160#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006161 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006162#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006163#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006164 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006165#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006166 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006167#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006168#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006169}
6170
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006171
Guido van Rossumb6775db1994-08-01 11:34:53 +00006172#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006174"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006176
Barry Warsaw53699e91996-12-10 23:23:01 +00006177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006179{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006180 PyObject* v;
6181 char buf[MAXPATHLEN];
6182 char *path;
6183 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006184#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006185 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006186#endif
6187
Victor Stinnerd6f85422010-05-05 23:33:33 +00006188 if (!PyArg_ParseTuple(args, "et:readlink",
6189 Py_FileSystemDefaultEncoding, &path))
6190 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006191#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006192 v = PySequence_GetItem(args, 0);
6193 if (v == NULL) {
6194 PyMem_Free(path);
6195 return NULL;
6196 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006197
Victor Stinnerd6f85422010-05-05 23:33:33 +00006198 if (PyUnicode_Check(v)) {
6199 arg_is_unicode = 1;
6200 }
6201 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006202#endif
6203
Victor Stinnerd6f85422010-05-05 23:33:33 +00006204 Py_BEGIN_ALLOW_THREADS
6205 n = readlink(path, buf, (int) sizeof buf);
6206 Py_END_ALLOW_THREADS
6207 if (n < 0)
6208 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006209
Victor Stinnerd6f85422010-05-05 23:33:33 +00006210 PyMem_Free(path);
6211 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006212#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006213 if (arg_is_unicode) {
6214 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006215
Victor Stinnerd6f85422010-05-05 23:33:33 +00006216 w = PyUnicode_FromEncodedObject(v,
6217 Py_FileSystemDefaultEncoding,
6218 "strict");
6219 if (w != NULL) {
6220 Py_DECREF(v);
6221 v = w;
6222 }
6223 else {
6224 /* fall back to the original byte string, as
6225 discussed in patch #683592 */
6226 PyErr_Clear();
6227 }
6228 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006229#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006230 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006231}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006232#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006234
Guido van Rossumb6775db1994-08-01 11:34:53 +00006235#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006236PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006237"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006238Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006239
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006241posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006242{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006243 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006244}
6245#endif /* HAVE_SYMLINK */
6246
6247
6248#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006249#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6250static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006251system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006252{
6253 ULONG value = 0;
6254
6255 Py_BEGIN_ALLOW_THREADS
6256 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6257 Py_END_ALLOW_THREADS
6258
6259 return value;
6260}
6261
6262static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006263posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006264{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006265 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006266 return Py_BuildValue("ddddd",
6267 (double)0 /* t.tms_utime / HZ */,
6268 (double)0 /* t.tms_stime / HZ */,
6269 (double)0 /* t.tms_cutime / HZ */,
6270 (double)0 /* t.tms_cstime / HZ */,
6271 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006272}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006273#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006274#define NEED_TICKS_PER_SECOND
6275static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006276static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006277posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006278{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006279 struct tms t;
6280 clock_t c;
6281 errno = 0;
6282 c = times(&t);
6283 if (c == (clock_t) -1)
6284 return posix_error();
6285 return Py_BuildValue("ddddd",
6286 (double)t.tms_utime / ticks_per_second,
6287 (double)t.tms_stime / ticks_per_second,
6288 (double)t.tms_cutime / ticks_per_second,
6289 (double)t.tms_cstime / ticks_per_second,
6290 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006291}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006292#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006293#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006294
6295
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006296#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006297#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006299posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006300{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006301 FILETIME create, exit, kernel, user;
6302 HANDLE hProc;
6303 hProc = GetCurrentProcess();
6304 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6305 /* The fields of a FILETIME structure are the hi and lo part
6306 of a 64-bit value expressed in 100 nanosecond units.
6307 1e7 is one second in such units; 1e-7 the inverse.
6308 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6309 */
6310 return Py_BuildValue(
6311 "ddddd",
6312 (double)(user.dwHighDateTime*429.4967296 +
6313 user.dwLowDateTime*1e-7),
6314 (double)(kernel.dwHighDateTime*429.4967296 +
6315 kernel.dwLowDateTime*1e-7),
6316 (double)0,
6317 (double)0,
6318 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006319}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006320#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006321
6322#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006324"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006326#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006329#ifdef HAVE_GETSID
6330PyDoc_STRVAR(posix_getsid__doc__,
6331"getsid(pid) -> sid\n\n\
6332Call the system call getsid().");
6333
6334static PyObject *
6335posix_getsid(PyObject *self, PyObject *args)
6336{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006337 pid_t pid;
6338 int sid;
6339 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6340 return NULL;
6341 sid = getsid(pid);
6342 if (sid < 0)
6343 return posix_error();
6344 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006345}
6346#endif /* HAVE_GETSID */
6347
6348
Guido van Rossumb6775db1994-08-01 11:34:53 +00006349#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006351"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006352Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006353
Barry Warsaw53699e91996-12-10 23:23:01 +00006354static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006355posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006356{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006357 if (setsid() < 0)
6358 return posix_error();
6359 Py_INCREF(Py_None);
6360 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006361}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006363
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006366"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006367Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006368
Barry Warsaw53699e91996-12-10 23:23:01 +00006369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006370posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006371{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006372 pid_t pid;
6373 int pgrp;
6374 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6375 return NULL;
6376 if (setpgid(pid, pgrp) < 0)
6377 return posix_error();
6378 Py_INCREF(Py_None);
6379 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006380}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006381#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006383
Guido van Rossumb6775db1994-08-01 11:34:53 +00006384#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006385PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006386"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006387Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006388
Barry Warsaw53699e91996-12-10 23:23:01 +00006389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006390posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006391{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006392 int fd;
6393 pid_t pgid;
6394 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6395 return NULL;
6396 pgid = tcgetpgrp(fd);
6397 if (pgid < 0)
6398 return posix_error();
6399 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006400}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006403
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006405PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006406"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006407Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006408
Barry Warsaw53699e91996-12-10 23:23:01 +00006409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006410posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006411{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006412 int fd;
6413 pid_t pgid;
6414 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6415 return NULL;
6416 if (tcsetpgrp(fd, pgid) < 0)
6417 return posix_error();
6418 Py_INCREF(Py_None);
6419 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006420}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006421#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006422
Guido van Rossum687dd131993-05-17 08:34:16 +00006423/* Functions acting on file descriptors */
6424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006426"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006427Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Barry Warsaw53699e91996-12-10 23:23:01 +00006429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006430posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006431{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006432 char *file = NULL;
6433 int flag;
6434 int mode = 0777;
6435 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006436
6437#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006438 PyUnicodeObject *po;
6439 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6440 Py_BEGIN_ALLOW_THREADS
6441 /* PyUnicode_AS_UNICODE OK without thread
6442 lock as it is a simple dereference. */
6443 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6444 Py_END_ALLOW_THREADS
6445 if (fd < 0)
6446 return posix_error();
6447 return PyInt_FromLong((long)fd);
6448 }
6449 /* Drop the argument parsing error as narrow strings
6450 are also valid. */
6451 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006452#endif
6453
Victor Stinnerd6f85422010-05-05 23:33:33 +00006454 if (!PyArg_ParseTuple(args, "eti|i",
6455 Py_FileSystemDefaultEncoding, &file,
6456 &flag, &mode))
6457 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006458
Victor Stinnerd6f85422010-05-05 23:33:33 +00006459 Py_BEGIN_ALLOW_THREADS
6460 fd = open(file, flag, mode);
6461 Py_END_ALLOW_THREADS
6462 if (fd < 0)
6463 return posix_error_with_allocated_filename(file);
6464 PyMem_Free(file);
6465 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006466}
6467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Barry Warsaw53699e91996-12-10 23:23:01 +00006473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006474posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006475{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006476 int fd, res;
6477 if (!PyArg_ParseTuple(args, "i:close", &fd))
6478 return NULL;
6479 if (!_PyVerify_fd(fd))
6480 return posix_error();
6481 Py_BEGIN_ALLOW_THREADS
6482 res = close(fd);
6483 Py_END_ALLOW_THREADS
6484 if (res < 0)
6485 return posix_error();
6486 Py_INCREF(Py_None);
6487 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006488}
6489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006490
Victor Stinnerd6f85422010-05-05 23:33:33 +00006491PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006492"closerange(fd_low, fd_high)\n\n\
6493Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6494
6495static PyObject *
6496posix_closerange(PyObject *self, PyObject *args)
6497{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006498 int fd_from, fd_to, i;
6499 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6500 return NULL;
6501 Py_BEGIN_ALLOW_THREADS
6502 for (i = fd_from; i < fd_to; i++)
6503 if (_PyVerify_fd(i))
6504 close(i);
6505 Py_END_ALLOW_THREADS
6506 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006507}
6508
6509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006510PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006511"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006513
Barry Warsaw53699e91996-12-10 23:23:01 +00006514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006515posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006516{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006517 int fd;
6518 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6519 return NULL;
6520 if (!_PyVerify_fd(fd))
6521 return posix_error();
6522 Py_BEGIN_ALLOW_THREADS
6523 fd = dup(fd);
6524 Py_END_ALLOW_THREADS
6525 if (fd < 0)
6526 return posix_error();
6527 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006528}
6529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006530
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006532"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006534
Barry Warsaw53699e91996-12-10 23:23:01 +00006535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006536posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006537{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006538 int fd, fd2, res;
6539 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6540 return NULL;
6541 if (!_PyVerify_fd_dup2(fd, fd2))
6542 return posix_error();
6543 Py_BEGIN_ALLOW_THREADS
6544 res = dup2(fd, fd2);
6545 Py_END_ALLOW_THREADS
6546 if (res < 0)
6547 return posix_error();
6548 Py_INCREF(Py_None);
6549 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006550}
6551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006552
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006554"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006555Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006556
Barry Warsaw53699e91996-12-10 23:23:01 +00006557static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006558posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006559{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006560 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006561#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006562 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006563#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006564 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006565#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006566 PyObject *posobj;
6567 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6568 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006569#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006570 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6571 switch (how) {
6572 case 0: how = SEEK_SET; break;
6573 case 1: how = SEEK_CUR; break;
6574 case 2: how = SEEK_END; break;
6575 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006576#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006577
6578#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006579 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006580#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006581 pos = PyLong_Check(posobj) ?
6582 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006583#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006584 if (PyErr_Occurred())
6585 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006586
Victor Stinnerd6f85422010-05-05 23:33:33 +00006587 if (!_PyVerify_fd(fd))
6588 return posix_error();
6589 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006590#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006591 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006592#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006593 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006594#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006595 Py_END_ALLOW_THREADS
6596 if (res < 0)
6597 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006598
6599#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006600 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006601#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006602 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006603#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006604}
6605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006606
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006608"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006609Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006610
Barry Warsaw53699e91996-12-10 23:23:01 +00006611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006612posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006613{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006614 int fd, size, n;
6615 PyObject *buffer;
6616 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6617 return NULL;
6618 if (size < 0) {
6619 errno = EINVAL;
6620 return posix_error();
6621 }
6622 buffer = PyString_FromStringAndSize((char *)NULL, size);
6623 if (buffer == NULL)
6624 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006625 if (!_PyVerify_fd(fd)) {
6626 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006627 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006628 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006629 Py_BEGIN_ALLOW_THREADS
6630 n = read(fd, PyString_AsString(buffer), size);
6631 Py_END_ALLOW_THREADS
6632 if (n < 0) {
6633 Py_DECREF(buffer);
6634 return posix_error();
6635 }
6636 if (n != size)
6637 _PyString_Resize(&buffer, n);
6638 return buffer;
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_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006643"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006644Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006645
Barry Warsaw53699e91996-12-10 23:23:01 +00006646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006647posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006648{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006649 Py_buffer pbuf;
6650 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006651 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006652
Victor Stinnerd6f85422010-05-05 23:33:33 +00006653 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6654 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006655 if (!_PyVerify_fd(fd)) {
6656 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006657 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006658 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006659 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006660 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006661#if defined(MS_WIN64) || defined(MS_WINDOWS)
6662 if (len > INT_MAX)
6663 len = INT_MAX;
6664 size = write(fd, pbuf.buf, (int)len);
6665#else
6666 size = write(fd, pbuf.buf, len);
6667#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006668 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006669 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006670 if (size < 0)
6671 return posix_error();
6672 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006673}
6674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006677"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006679
Barry Warsaw53699e91996-12-10 23:23:01 +00006680static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006681posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006682{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006683 int fd;
6684 STRUCT_STAT st;
6685 int res;
6686 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6687 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006688#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006689 /* on OpenVMS we must ensure that all bytes are written to the file */
6690 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006691#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006692 if (!_PyVerify_fd(fd))
6693 return posix_error();
6694 Py_BEGIN_ALLOW_THREADS
6695 res = FSTAT(fd, &st);
6696 Py_END_ALLOW_THREADS
6697 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006698#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006699 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006700#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006701 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006702#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006703 }
Tim Peters5aa91602002-01-30 05:46:57 +00006704
Victor Stinnerd6f85422010-05-05 23:33:33 +00006705 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006706}
6707
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006708
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006710"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006711Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006712
Barry Warsaw53699e91996-12-10 23:23:01 +00006713static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006714posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006715{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006716 int fd;
6717 char *orgmode = "r";
6718 int bufsize = -1;
6719 FILE *fp;
6720 PyObject *f;
6721 char *mode;
6722 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6723 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006724
Victor Stinnerd6f85422010-05-05 23:33:33 +00006725 /* Sanitize mode. See fileobject.c */
6726 mode = PyMem_MALLOC(strlen(orgmode)+3);
6727 if (!mode) {
6728 PyErr_NoMemory();
6729 return NULL;
6730 }
6731 strcpy(mode, orgmode);
6732 if (_PyFile_SanitizeMode(mode)) {
6733 PyMem_FREE(mode);
6734 return NULL;
6735 }
6736 if (!_PyVerify_fd(fd))
6737 return posix_error();
6738 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006739#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006740 if (mode[0] == 'a') {
6741 /* try to make sure the O_APPEND flag is set */
6742 int flags;
6743 flags = fcntl(fd, F_GETFL);
6744 if (flags != -1)
6745 fcntl(fd, F_SETFL, flags | O_APPEND);
6746 fp = fdopen(fd, mode);
6747 if (fp == NULL && flags != -1)
6748 /* restore old mode if fdopen failed */
6749 fcntl(fd, F_SETFL, flags);
6750 } else {
6751 fp = fdopen(fd, mode);
6752 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006753#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006754 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006755#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006756 Py_END_ALLOW_THREADS
6757 PyMem_FREE(mode);
6758 if (fp == NULL)
6759 return posix_error();
Nadeem Vawdad7664de2012-01-19 00:40:46 +02006760 /* The dummy filename used here must be kept in sync with the value
6761 tested against in gzip.GzipFile.__init__() - see issue #13781. */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006762 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6763 if (f != NULL)
6764 PyFile_SetBufSize(f, bufsize);
6765 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006766}
6767
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006768PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006769"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006770Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006771connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006772
6773static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006774posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006775{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006776 int fd;
6777 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6778 return NULL;
6779 if (!_PyVerify_fd(fd))
6780 return PyBool_FromLong(0);
6781 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006782}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006783
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006784#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006785PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006786"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006787Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006788
Barry Warsaw53699e91996-12-10 23:23:01 +00006789static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006790posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006791{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006792#if defined(PYOS_OS2)
6793 HFILE read, write;
6794 APIRET rc;
6795
Victor Stinnerd6f85422010-05-05 23:33:33 +00006796 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006797 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006798 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006799 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006800 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006801
6802 return Py_BuildValue("(ii)", read, write);
6803#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006804#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006805 int fds[2];
6806 int res;
6807 Py_BEGIN_ALLOW_THREADS
6808 res = pipe(fds);
6809 Py_END_ALLOW_THREADS
6810 if (res != 0)
6811 return posix_error();
6812 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006813#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006814 HANDLE read, write;
6815 int read_fd, write_fd;
6816 BOOL ok;
6817 Py_BEGIN_ALLOW_THREADS
6818 ok = CreatePipe(&read, &write, NULL, 0);
6819 Py_END_ALLOW_THREADS
6820 if (!ok)
6821 return win32_error("CreatePipe", NULL);
6822 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6823 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6824 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006825#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006826#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006827}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006828#endif /* HAVE_PIPE */
6829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006830
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006831#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006832PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006833"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006834Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006835
Barry Warsaw53699e91996-12-10 23:23:01 +00006836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006837posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006838{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006839 char *filename;
6840 int mode = 0666;
6841 int res;
6842 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6843 return NULL;
6844 Py_BEGIN_ALLOW_THREADS
6845 res = mkfifo(filename, mode);
6846 Py_END_ALLOW_THREADS
6847 if (res < 0)
6848 return posix_error();
6849 Py_INCREF(Py_None);
6850 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006851}
6852#endif
6853
6854
Neal Norwitz11690112002-07-30 01:08:28 +00006855#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006857"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006858Create a filesystem node (file, device special file or named pipe)\n\
6859named filename. mode specifies both the permissions to use and the\n\
6860type of node to be created, being combined (bitwise OR) with one of\n\
6861S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006862device defines the newly created device special file (probably using\n\
6863os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006864
6865
6866static PyObject *
6867posix_mknod(PyObject *self, PyObject *args)
6868{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006869 char *filename;
6870 int mode = 0600;
6871 int device = 0;
6872 int res;
6873 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6874 return NULL;
6875 Py_BEGIN_ALLOW_THREADS
6876 res = mknod(filename, mode, device);
6877 Py_END_ALLOW_THREADS
6878 if (res < 0)
6879 return posix_error();
6880 Py_INCREF(Py_None);
6881 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006882}
6883#endif
6884
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006885#ifdef HAVE_DEVICE_MACROS
6886PyDoc_STRVAR(posix_major__doc__,
6887"major(device) -> major number\n\
6888Extracts a device major number from a raw device number.");
6889
6890static PyObject *
6891posix_major(PyObject *self, PyObject *args)
6892{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006893 int device;
6894 if (!PyArg_ParseTuple(args, "i:major", &device))
6895 return NULL;
6896 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006897}
6898
6899PyDoc_STRVAR(posix_minor__doc__,
6900"minor(device) -> minor number\n\
6901Extracts a device minor number from a raw device number.");
6902
6903static PyObject *
6904posix_minor(PyObject *self, PyObject *args)
6905{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006906 int device;
6907 if (!PyArg_ParseTuple(args, "i:minor", &device))
6908 return NULL;
6909 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006910}
6911
6912PyDoc_STRVAR(posix_makedev__doc__,
6913"makedev(major, minor) -> device number\n\
6914Composes a raw device number from the major and minor device numbers.");
6915
6916static PyObject *
6917posix_makedev(PyObject *self, PyObject *args)
6918{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006919 int major, minor;
6920 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6921 return NULL;
6922 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006923}
6924#endif /* device macros */
6925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006926
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006927#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006928PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006929"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006930Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006931
Barry Warsaw53699e91996-12-10 23:23:01 +00006932static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006933posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006934{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006935 int fd;
6936 off_t length;
6937 int res;
6938 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006939
Victor Stinnerd6f85422010-05-05 23:33:33 +00006940 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6941 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006942
6943#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006944 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006945#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006946 length = PyLong_Check(lenobj) ?
6947 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006948#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006949 if (PyErr_Occurred())
6950 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006951
Victor Stinnerd6f85422010-05-05 23:33:33 +00006952 Py_BEGIN_ALLOW_THREADS
6953 res = ftruncate(fd, length);
6954 Py_END_ALLOW_THREADS
6955 if (res < 0)
6956 return posix_error();
6957 Py_INCREF(Py_None);
6958 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006959}
6960#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006961
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006962#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006963PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006964"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006965Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006966
Fred Drake762e2061999-08-26 17:23:54 +00006967/* Save putenv() parameters as values here, so we can collect them when they
6968 * get re-set with another call for the same key. */
6969static PyObject *posix_putenv_garbage;
6970
Tim Peters5aa91602002-01-30 05:46:57 +00006971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006972posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006973{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006974 char *s1, *s2;
6975 char *newenv;
6976 PyObject *newstr;
6977 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006978
Victor Stinnerd6f85422010-05-05 23:33:33 +00006979 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6980 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006981
6982#if defined(PYOS_OS2)
6983 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6984 APIRET rc;
6985
Guido van Rossumd48f2521997-12-05 22:19:34 +00006986 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6987 if (rc != NO_ERROR)
6988 return os2_error(rc);
6989
6990 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6991 APIRET rc;
6992
Guido van Rossumd48f2521997-12-05 22:19:34 +00006993 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6994 if (rc != NO_ERROR)
6995 return os2_error(rc);
6996 } else {
6997#endif
6998
Victor Stinnerd6f85422010-05-05 23:33:33 +00006999 /* XXX This can leak memory -- not easy to fix :-( */
7000 len = strlen(s1) + strlen(s2) + 2;
Victor Stinner53853c32011-11-22 22:20:13 +01007001#ifdef MS_WINDOWS
7002 if (_MAX_ENV < (len - 1)) {
7003 PyErr_Format(PyExc_ValueError,
7004 "the environment variable is longer than %u bytes",
7005 _MAX_ENV);
7006 return NULL;
7007 }
7008#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007009 /* len includes space for a trailing \0; the size arg to
7010 PyString_FromStringAndSize does not count that */
7011 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7012 if (newstr == NULL)
7013 return PyErr_NoMemory();
7014 newenv = PyString_AS_STRING(newstr);
7015 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7016 if (putenv(newenv)) {
7017 Py_DECREF(newstr);
7018 posix_error();
7019 return NULL;
7020 }
7021 /* Install the first arg and newstr in posix_putenv_garbage;
7022 * this will cause previous value to be collected. This has to
7023 * happen after the real putenv() call because the old value
7024 * was still accessible until then. */
7025 if (PyDict_SetItem(posix_putenv_garbage,
7026 PyTuple_GET_ITEM(args, 0), newstr)) {
7027 /* really not much we can do; just leak */
7028 PyErr_Clear();
7029 }
7030 else {
7031 Py_DECREF(newstr);
7032 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007033
7034#if defined(PYOS_OS2)
7035 }
7036#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007037 Py_INCREF(Py_None);
7038 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007039}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007040#endif /* putenv */
7041
Guido van Rossumc524d952001-10-19 01:31:59 +00007042#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007043PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007044"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007045Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007046
7047static PyObject *
7048posix_unsetenv(PyObject *self, PyObject *args)
7049{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007050 char *s1;
Charles-François Natali93a11752011-11-27 13:01:35 +01007051#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner53853c32011-11-22 22:20:13 +01007052 int err;
Charles-François Natali93a11752011-11-27 13:01:35 +01007053#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007054
Victor Stinnerd6f85422010-05-05 23:33:33 +00007055 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7056 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007057
Charles-François Natali93a11752011-11-27 13:01:35 +01007058#ifdef HAVE_BROKEN_UNSETENV
7059 unsetenv(s1);
7060#else
Victor Stinner53853c32011-11-22 22:20:13 +01007061 err = unsetenv(s1);
Benjamin Peterson42d96dc2011-11-22 23:56:06 -06007062 if (err)
Victor Stinner53853c32011-11-22 22:20:13 +01007063 return posix_error();
Charles-François Natali93a11752011-11-27 13:01:35 +01007064#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007065
Victor Stinnerd6f85422010-05-05 23:33:33 +00007066 /* Remove the key from posix_putenv_garbage;
7067 * this will cause it to be collected. This has to
7068 * happen after the real unsetenv() call because the
7069 * old value was still accessible until then.
7070 */
7071 if (PyDict_DelItem(posix_putenv_garbage,
7072 PyTuple_GET_ITEM(args, 0))) {
7073 /* really not much we can do; just leak */
7074 PyErr_Clear();
7075 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007076
Victor Stinnerd6f85422010-05-05 23:33:33 +00007077 Py_INCREF(Py_None);
7078 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007079}
7080#endif /* unsetenv */
7081
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007082PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007083"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007084Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007085
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007087posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007088{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007089 int code;
7090 char *message;
7091 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7092 return NULL;
7093 message = strerror(code);
7094 if (message == NULL) {
7095 PyErr_SetString(PyExc_ValueError,
7096 "strerror() argument out of range");
7097 return NULL;
7098 }
7099 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007100}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007101
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007102
Guido van Rossumc9641791998-08-04 15:26:23 +00007103#ifdef HAVE_SYS_WAIT_H
7104
Fred Drake106c1a02002-04-23 15:58:02 +00007105#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007106PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007107"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007108Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007109
7110static PyObject *
7111posix_WCOREDUMP(PyObject *self, PyObject *args)
7112{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007113 WAIT_TYPE status;
7114 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007115
Victor Stinnerd6f85422010-05-05 23:33:33 +00007116 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7117 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007118
Victor Stinnerd6f85422010-05-05 23:33:33 +00007119 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007120}
7121#endif /* WCOREDUMP */
7122
7123#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007124PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007125"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007126Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007127job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007128
7129static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007130posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007131{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007132 WAIT_TYPE status;
7133 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007134
Victor Stinnerd6f85422010-05-05 23:33:33 +00007135 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7136 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007137
Victor Stinnerd6f85422010-05-05 23:33:33 +00007138 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007139}
7140#endif /* WIFCONTINUED */
7141
Guido van Rossumc9641791998-08-04 15:26:23 +00007142#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007143PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007144"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007145Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007146
7147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007148posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007149{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007150 WAIT_TYPE status;
7151 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007152
Victor Stinnerd6f85422010-05-05 23:33:33 +00007153 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7154 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007155
Victor Stinnerd6f85422010-05-05 23:33:33 +00007156 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007157}
7158#endif /* WIFSTOPPED */
7159
7160#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007161PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007162"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007163Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007164
7165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007166posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007167{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007168 WAIT_TYPE status;
7169 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007170
Victor Stinnerd6f85422010-05-05 23:33:33 +00007171 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7172 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007173
Victor Stinnerd6f85422010-05-05 23:33:33 +00007174 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007175}
7176#endif /* WIFSIGNALED */
7177
7178#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007179PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007180"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007181Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007182system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007183
7184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007185posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007186{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007187 WAIT_TYPE status;
7188 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007189
Victor Stinnerd6f85422010-05-05 23:33:33 +00007190 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7191 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007192
Victor Stinnerd6f85422010-05-05 23:33:33 +00007193 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007194}
7195#endif /* WIFEXITED */
7196
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007197#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007198PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007199"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007200Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007201
7202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007203posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007204{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007205 WAIT_TYPE status;
7206 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007207
Victor Stinnerd6f85422010-05-05 23:33:33 +00007208 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7209 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007210
Victor Stinnerd6f85422010-05-05 23:33:33 +00007211 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007212}
7213#endif /* WEXITSTATUS */
7214
7215#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007216PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007217"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007218Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007219value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007220
7221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007222posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007223{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007224 WAIT_TYPE status;
7225 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007226
Victor Stinnerd6f85422010-05-05 23:33:33 +00007227 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7228 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007229
Victor Stinnerd6f85422010-05-05 23:33:33 +00007230 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007231}
7232#endif /* WTERMSIG */
7233
7234#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007235PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007236"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007237Return the signal that stopped the process that provided\n\
7238the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007239
7240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007241posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007242{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007243 WAIT_TYPE status;
7244 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007245
Victor Stinnerd6f85422010-05-05 23:33:33 +00007246 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7247 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007248
Victor Stinnerd6f85422010-05-05 23:33:33 +00007249 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007250}
7251#endif /* WSTOPSIG */
7252
7253#endif /* HAVE_SYS_WAIT_H */
7254
7255
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007256#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007257#ifdef _SCO_DS
7258/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7259 needed definitions in sys/statvfs.h */
7260#define _SVID3
7261#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007262#include <sys/statvfs.h>
7263
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007264static PyObject*
7265_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007266 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7267 if (v == NULL)
7268 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007269
7270#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007271 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7272 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7273 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7274 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7275 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7276 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7277 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7278 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7279 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7280 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007281#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007282 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7283 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7284 PyStructSequence_SET_ITEM(v, 2,
7285 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7286 PyStructSequence_SET_ITEM(v, 3,
7287 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7288 PyStructSequence_SET_ITEM(v, 4,
7289 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7290 PyStructSequence_SET_ITEM(v, 5,
7291 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7292 PyStructSequence_SET_ITEM(v, 6,
7293 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7294 PyStructSequence_SET_ITEM(v, 7,
7295 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7296 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7297 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007298#endif
7299
Victor Stinnerd6f85422010-05-05 23:33:33 +00007300 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007301}
7302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007303PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007304"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007305Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007306
7307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007308posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007309{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007310 int fd, res;
7311 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007312
Victor Stinnerd6f85422010-05-05 23:33:33 +00007313 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7314 return NULL;
7315 Py_BEGIN_ALLOW_THREADS
7316 res = fstatvfs(fd, &st);
7317 Py_END_ALLOW_THREADS
7318 if (res != 0)
7319 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007320
Victor Stinnerd6f85422010-05-05 23:33:33 +00007321 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007322}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007323#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007324
7325
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007326#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007327#include <sys/statvfs.h>
7328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007329PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007330"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007331Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007332
7333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007334posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007335{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007336 char *path;
7337 int res;
7338 struct statvfs st;
7339 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7340 return NULL;
7341 Py_BEGIN_ALLOW_THREADS
7342 res = statvfs(path, &st);
7343 Py_END_ALLOW_THREADS
7344 if (res != 0)
7345 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007346
Victor Stinnerd6f85422010-05-05 23:33:33 +00007347 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007348}
7349#endif /* HAVE_STATVFS */
7350
7351
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007352#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007353PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007354"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007355Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007356The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007357or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007358
7359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007360posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007361{
7362 PyObject *result = NULL;
7363 char *dir = NULL;
7364 char *pfx = NULL;
7365 char *name;
7366
7367 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007368 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007369
7370 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007371 "tempnam is a potential security risk to your program") < 0)
7372 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007373
Antoine Pitroub0614612011-01-02 20:04:52 +00007374 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7375 "use the tempfile module", 1) < 0)
7376 return NULL;
7377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007378#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007379 name = _tempnam(dir, pfx);
7380#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007381 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007382#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007383 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007384 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007385 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386 free(name);
7387 return result;
7388}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007389#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007390
7391
7392#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007393PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007394"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007395Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007396
7397static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007398posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007399{
7400 FILE *fp;
7401
Antoine Pitroub0614612011-01-02 20:04:52 +00007402 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7403 "use the tempfile module", 1) < 0)
7404 return NULL;
7405
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007406 fp = tmpfile();
7407 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007408 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007409 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007410}
7411#endif
7412
7413
7414#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007415PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007416"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007417Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007418
7419static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007420posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007421{
7422 char buffer[L_tmpnam];
7423 char *name;
7424
Skip Montanaro95618b52001-08-18 18:52:10 +00007425 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007426 "tmpnam is a potential security risk to your program") < 0)
7427 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007428
Antoine Pitroub0614612011-01-02 20:04:52 +00007429 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7430 "use the tempfile module", 1) < 0)
7431 return NULL;
7432
Greg Wardb48bc172000-03-01 21:51:56 +00007433#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007434 name = tmpnam_r(buffer);
7435#else
7436 name = tmpnam(buffer);
7437#endif
7438 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007439 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007440#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007441 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007442#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007443 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007444#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007445 );
7446 PyErr_SetObject(PyExc_OSError, err);
7447 Py_XDECREF(err);
7448 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007449 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007450 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007451}
7452#endif
7453
7454
Fred Drakec9680921999-12-13 16:37:25 +00007455/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7456 * It maps strings representing configuration variable names to
7457 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007458 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007459 * rarely-used constants. There are three separate tables that use
7460 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007461 *
7462 * This code is always included, even if none of the interfaces that
7463 * need it are included. The #if hackery needed to avoid it would be
7464 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007465 */
7466struct constdef {
7467 char *name;
7468 long value;
7469};
7470
Fred Drake12c6e2d1999-12-14 21:25:03 +00007471static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007472conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007473 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007474{
7475 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007476 *valuep = PyInt_AS_LONG(arg);
7477 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007478 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007479 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007480 /* look up the value in the table using a binary search */
7481 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007482 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007483 size_t hi = tablesize;
7484 int cmp;
7485 char *confname = PyString_AS_STRING(arg);
7486 while (lo < hi) {
7487 mid = (lo + hi) / 2;
7488 cmp = strcmp(confname, table[mid].name);
7489 if (cmp < 0)
7490 hi = mid;
7491 else if (cmp > 0)
7492 lo = mid + 1;
7493 else {
7494 *valuep = table[mid].value;
7495 return 1;
7496 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007497 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007498 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007499 }
7500 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007501 PyErr_SetString(PyExc_TypeError,
7502 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007503 return 0;
7504}
7505
7506
7507#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7508static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007509#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007510 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007511#endif
7512#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007513 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007514#endif
Fred Drakec9680921999-12-13 16:37:25 +00007515#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007516 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007517#endif
7518#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007519 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007520#endif
7521#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007522 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007523#endif
7524#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007525 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007526#endif
7527#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007528 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007529#endif
7530#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007531 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007532#endif
7533#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007534 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007535#endif
7536#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007537 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007538#endif
7539#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007540 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007541#endif
7542#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007543 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007544#endif
7545#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007546 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007547#endif
7548#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007549 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007550#endif
7551#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007552 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007553#endif
7554#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007555 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007556#endif
7557#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007558 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007559#endif
7560};
7561
Fred Drakec9680921999-12-13 16:37:25 +00007562static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007563conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007564{
7565 return conv_confname(arg, valuep, posix_constants_pathconf,
7566 sizeof(posix_constants_pathconf)
7567 / sizeof(struct constdef));
7568}
7569#endif
7570
7571#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007572PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007573"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007574Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007575If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007576
7577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007578posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007579{
7580 PyObject *result = NULL;
7581 int name, fd;
7582
Fred Drake12c6e2d1999-12-14 21:25:03 +00007583 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7584 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007585 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007586
Stefan Krah93f7a322010-11-26 17:35:50 +00007587 errno = 0;
7588 limit = fpathconf(fd, name);
7589 if (limit == -1 && errno != 0)
7590 posix_error();
7591 else
7592 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007593 }
7594 return result;
7595}
7596#endif
7597
7598
7599#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007600PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007601"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007602Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007603If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007604
7605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007606posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007607{
7608 PyObject *result = NULL;
7609 int name;
7610 char *path;
7611
7612 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7613 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007614 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007615
Victor Stinnerd6f85422010-05-05 23:33:33 +00007616 errno = 0;
7617 limit = pathconf(path, name);
7618 if (limit == -1 && errno != 0) {
7619 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007620 /* could be a path or name problem */
7621 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007622 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007623 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007624 }
7625 else
7626 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007627 }
7628 return result;
7629}
7630#endif
7631
7632#ifdef HAVE_CONFSTR
7633static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007634#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007635 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007636#endif
7637#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007638 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007639#endif
7640#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007641 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007642#endif
7643#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007644 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007645#endif
7646#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007647 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007648#endif
Fred Drakec9680921999-12-13 16:37:25 +00007649#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007650 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007651#endif
7652#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007653 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007654#endif
7655#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007656 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007657#endif
7658#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007659 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007660#endif
7661#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007662 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007663#endif
7664#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007665 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007666#endif
7667#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007668 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007669#endif
7670#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007671 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007672#endif
Fred Draked86ed291999-12-15 15:34:33 +00007673#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007674 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007675#endif
Fred Drakec9680921999-12-13 16:37:25 +00007676#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007677 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007678#endif
Fred Draked86ed291999-12-15 15:34:33 +00007679#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007680 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007681#endif
7682#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007683 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007684#endif
7685#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007686 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007687#endif
7688#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007689 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007690#endif
Fred Drakec9680921999-12-13 16:37:25 +00007691#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007692 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007693#endif
7694#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007696#endif
7697#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007698 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007699#endif
7700#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007701 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007702#endif
7703#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007704 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007705#endif
7706#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007708#endif
7709#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007711#endif
7712#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007713 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007714#endif
7715#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007716 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007717#endif
7718#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007719 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007720#endif
7721#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007722 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007723#endif
7724#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007725 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007726#endif
7727#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007728 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007729#endif
7730#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007731 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007732#endif
7733#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007735#endif
7736#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007737 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007738#endif
Fred Draked86ed291999-12-15 15:34:33 +00007739#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007740 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007741#endif
7742#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007743 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007744#endif
7745#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007746 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007747#endif
7748#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007749 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007750#endif
7751#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007752 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007753#endif
7754#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007755 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007756#endif
7757#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007758 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007759#endif
7760#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007761 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007762#endif
7763#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007764 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007765#endif
7766#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007767 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007768#endif
7769#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007770 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007771#endif
7772#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007773 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007774#endif
7775#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007776 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007777#endif
Fred Drakec9680921999-12-13 16:37:25 +00007778};
7779
7780static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007781conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007782{
7783 return conv_confname(arg, valuep, posix_constants_confstr,
7784 sizeof(posix_constants_confstr)
7785 / sizeof(struct constdef));
7786}
7787
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007788PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007789"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007790Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007791
7792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007793posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007794{
7795 PyObject *result = NULL;
7796 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007797 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007798
7799 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007800 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007801
Victor Stinnerd6f85422010-05-05 23:33:33 +00007802 errno = 0;
7803 len = confstr(name, buffer, sizeof(buffer));
7804 if (len == 0) {
7805 if (errno) {
7806 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007807 }
7808 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007809 result = Py_None;
7810 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007811 }
7812 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 else {
7814 if ((unsigned int)len >= sizeof(buffer)) {
7815 result = PyString_FromStringAndSize(NULL, len-1);
7816 if (result != NULL)
7817 confstr(name, PyString_AS_STRING(result), len);
7818 }
7819 else
7820 result = PyString_FromStringAndSize(buffer, len-1);
7821 }
7822 }
Fred Drakec9680921999-12-13 16:37:25 +00007823 return result;
7824}
7825#endif
7826
7827
7828#ifdef HAVE_SYSCONF
7829static struct constdef posix_constants_sysconf[] = {
7830#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007831 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007832#endif
7833#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007834 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007835#endif
7836#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007837 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007838#endif
7839#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007840 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007841#endif
7842#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007843 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007844#endif
7845#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007846 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007847#endif
7848#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007850#endif
7851#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007853#endif
7854#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007856#endif
7857#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007859#endif
Fred Draked86ed291999-12-15 15:34:33 +00007860#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007862#endif
7863#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007865#endif
Fred Drakec9680921999-12-13 16:37:25 +00007866#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
Fred Drakec9680921999-12-13 16:37:25 +00007869#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
7881#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007883#endif
Fred Draked86ed291999-12-15 15:34:33 +00007884#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007886#endif
Fred Drakec9680921999-12-13 16:37:25 +00007887#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007889#endif
7890#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007892#endif
7893#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007895#endif
7896#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007898#endif
7899#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007901#endif
Fred Draked86ed291999-12-15 15:34:33 +00007902#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007904#endif
Fred Drakec9680921999-12-13 16:37:25 +00007905#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
7908#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007910#endif
7911#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007913#endif
7914#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007916#endif
7917#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
7920#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007922#endif
7923#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
7926#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007928#endif
7929#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
7932#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007934#endif
7935#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007937#endif
7938#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007940#endif
7941#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007943#endif
7944#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007946#endif
7947#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007949#endif
7950#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007951 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007952#endif
7953#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007954 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007955#endif
7956#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007957 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007958#endif
7959#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007960 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007961#endif
7962#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007963 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007964#endif
7965#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007966 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007967#endif
7968#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007969 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007970#endif
7971#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007973#endif
Fred Draked86ed291999-12-15 15:34:33 +00007974#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007975 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007976#endif
Fred Drakec9680921999-12-13 16:37:25 +00007977#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007979#endif
7980#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007982#endif
7983#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007984 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007985#endif
Fred Draked86ed291999-12-15 15:34:33 +00007986#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007987 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007988#endif
Fred Drakec9680921999-12-13 16:37:25 +00007989#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007990 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007991#endif
Fred Draked86ed291999-12-15 15:34:33 +00007992#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007993 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007994#endif
7995#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007996 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007997#endif
Fred Drakec9680921999-12-13 16:37:25 +00007998#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007999 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008000#endif
8001#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008002 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008003#endif
8004#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008005 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008006#endif
8007#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008008 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008009#endif
Fred Draked86ed291999-12-15 15:34:33 +00008010#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008011 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00008012#endif
Fred Drakec9680921999-12-13 16:37:25 +00008013#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008014 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00008015#endif
8016#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008017 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00008018#endif
8019#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008020 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008021#endif
8022#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008023 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008024#endif
8025#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008026 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008027#endif
8028#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008029 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008030#endif
8031#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008032 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008033#endif
Fred Draked86ed291999-12-15 15:34:33 +00008034#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008035 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008036#endif
Fred Drakec9680921999-12-13 16:37:25 +00008037#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008038 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008039#endif
8040#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008041 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008042#endif
Fred Draked86ed291999-12-15 15:34:33 +00008043#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008044 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008045#endif
Fred Drakec9680921999-12-13 16:37:25 +00008046#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008047 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008048#endif
8049#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008050 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008051#endif
8052#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008053 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008054#endif
8055#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008056 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008057#endif
8058#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008059 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008060#endif
8061#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008062 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
8064#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008065 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008066#endif
8067#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008068 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008069#endif
8070#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008071 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008072#endif
Fred Draked86ed291999-12-15 15:34:33 +00008073#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008074 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008075#endif
8076#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008077 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008078#endif
Fred Drakec9680921999-12-13 16:37:25 +00008079#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008080 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
8082#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008083 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008084#endif
8085#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008086 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008087#endif
8088#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008089 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008090#endif
8091#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008092 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008093#endif
8094#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008095 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008096#endif
8097#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008098 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008099#endif
8100#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008101 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008102#endif
8103#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008104 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008105#endif
8106#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008107 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008108#endif
8109#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008110 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008111#endif
8112#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008113 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008114#endif
8115#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008116 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008117#endif
8118#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008119 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008120#endif
8121#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008122 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008123#endif
8124#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008125 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008126#endif
8127#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008128 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008129#endif
8130#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008131 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008132#endif
8133#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008134 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008135#endif
8136#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008137 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008138#endif
8139#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008140 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008141#endif
8142#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008143 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008144#endif
8145#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008146 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008147#endif
8148#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008149 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008150#endif
8151#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008152 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008153#endif
8154#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008155 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008156#endif
8157#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008158 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008159#endif
8160#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008161 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008162#endif
8163#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008164 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008165#endif
8166#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008167 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008168#endif
8169#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008170 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008171#endif
8172#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008173 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008174#endif
8175#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008176 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008177#endif
8178#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008179 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008180#endif
8181#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008182 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008183#endif
Fred Draked86ed291999-12-15 15:34:33 +00008184#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008185 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008186#endif
Fred Drakec9680921999-12-13 16:37:25 +00008187#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008188 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008189#endif
8190#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008191 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008192#endif
8193#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008194 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008195#endif
8196#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008197 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008198#endif
8199#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008200 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008201#endif
8202#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008203 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008204#endif
8205#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008206 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008207#endif
8208#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008209 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008210#endif
8211#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008212 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008213#endif
8214#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008215 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008218 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008221 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
8223#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008224 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008225#endif
8226#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008227 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008230 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
8232#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008233 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008234#endif
8235#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008236 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008239 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008242 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008245 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
8247#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008248 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008251 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008254 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008257 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
8259#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008260 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008261#endif
8262#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008263 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008264#endif
8265#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008266 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008267#endif
8268#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008269 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008270#endif
8271#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008272 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008273#endif
8274#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008275 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
8277#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008278 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008281 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008284 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
8286#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008287 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008288#endif
8289#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008290 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008291#endif
8292#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008293 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008294#endif
8295#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008296 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008297#endif
8298#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008299 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008300#endif
8301#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008302 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008303#endif
8304#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008305 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008306#endif
8307#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008308 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008309#endif
8310#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008311 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008312#endif
8313#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008314 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008315#endif
8316#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008317 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008318#endif
8319#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008320 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008321#endif
8322};
8323
8324static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008325conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008326{
8327 return conv_confname(arg, valuep, posix_constants_sysconf,
8328 sizeof(posix_constants_sysconf)
8329 / sizeof(struct constdef));
8330}
8331
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008332PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008333"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008334Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008335
8336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008337posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008338{
8339 PyObject *result = NULL;
8340 int name;
8341
8342 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008343 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008344
Victor Stinner862490a2010-05-06 00:03:44 +00008345 errno = 0;
8346 value = sysconf(name);
8347 if (value == -1 && errno != 0)
8348 posix_error();
8349 else
8350 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008351 }
8352 return result;
8353}
8354#endif
8355
8356
Fred Drakebec628d1999-12-15 18:31:10 +00008357/* This code is used to ensure that the tables of configuration value names
8358 * are in sorted order as required by conv_confname(), and also to build the
8359 * the exported dictionaries that are used to publish information about the
8360 * names available on the host platform.
8361 *
8362 * Sorting the table at runtime ensures that the table is properly ordered
8363 * when used, even for platforms we're not able to test on. It also makes
8364 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008365 */
Fred Drakebec628d1999-12-15 18:31:10 +00008366
8367static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008368cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008369{
8370 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008371 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008372 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008373 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008374
8375 return strcmp(c1->name, c2->name);
8376}
8377
8378static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008379setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008380 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008381{
Fred Drakebec628d1999-12-15 18:31:10 +00008382 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008383 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008384
8385 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8386 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008387 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008388 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008389
Barry Warsaw3155db32000-04-13 15:20:40 +00008390 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008391 PyObject *o = PyInt_FromLong(table[i].value);
8392 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8393 Py_XDECREF(o);
8394 Py_DECREF(d);
8395 return -1;
8396 }
8397 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008398 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008399 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008400}
8401
Fred Drakebec628d1999-12-15 18:31:10 +00008402/* Return -1 on failure, 0 on success. */
8403static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008404setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008405{
8406#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008407 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008408 sizeof(posix_constants_pathconf)
8409 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008410 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008411 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008412#endif
8413#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008414 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008415 sizeof(posix_constants_confstr)
8416 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008417 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008418 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008419#endif
8420#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008421 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008422 sizeof(posix_constants_sysconf)
8423 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008424 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008425 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008426#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008427 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008428}
Fred Draked86ed291999-12-15 15:34:33 +00008429
8430
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008431PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008432"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008433Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008434in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008435
8436static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008437posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008438{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008439 abort();
8440 /*NOTREACHED*/
8441 Py_FatalError("abort() called from Python code didn't abort!");
8442 return NULL;
8443}
Fred Drakebec628d1999-12-15 18:31:10 +00008444
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008445#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008446PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008447"startfile(filepath [, operation]) - Start a file with its associated\n\
8448application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008449\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008450When \"operation\" is not specified or \"open\", this acts like\n\
8451double-clicking the file in Explorer, or giving the file name as an\n\
8452argument to the DOS \"start\" command: the file is opened with whatever\n\
8453application (if any) its extension is associated.\n\
8454When another \"operation\" is given, it specifies what should be done with\n\
8455the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008456\n\
8457startfile returns as soon as the associated application is launched.\n\
8458There is no option to wait for the application to close, and no way\n\
8459to retrieve the application's exit status.\n\
8460\n\
8461The filepath is relative to the current directory. If you want to use\n\
8462an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008463the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008464
8465static PyObject *
8466win32_startfile(PyObject *self, PyObject *args)
8467{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 char *filepath;
8469 char *operation = NULL;
8470 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008471
Victor Stinnerd6f85422010-05-05 23:33:33 +00008472 PyObject *unipath, *woperation = NULL;
8473 if (!PyArg_ParseTuple(args, "U|s:startfile",
8474 &unipath, &operation)) {
8475 PyErr_Clear();
8476 goto normal;
8477 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008478
Victor Stinnerd6f85422010-05-05 23:33:33 +00008479 if (operation) {
8480 woperation = PyUnicode_DecodeASCII(operation,
8481 strlen(operation), NULL);
8482 if (!woperation) {
8483 PyErr_Clear();
8484 operation = NULL;
8485 goto normal;
8486 }
8487 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008488
Victor Stinnerd6f85422010-05-05 23:33:33 +00008489 Py_BEGIN_ALLOW_THREADS
8490 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8491 PyUnicode_AS_UNICODE(unipath),
8492 NULL, NULL, SW_SHOWNORMAL);
8493 Py_END_ALLOW_THREADS
8494
8495 Py_XDECREF(woperation);
8496 if (rc <= (HINSTANCE)32) {
8497 PyObject *errval = win32_error_unicode("startfile",
8498 PyUnicode_AS_UNICODE(unipath));
8499 return errval;
8500 }
8501 Py_INCREF(Py_None);
8502 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008503
8504normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008505 if (!PyArg_ParseTuple(args, "et|s:startfile",
8506 Py_FileSystemDefaultEncoding, &filepath,
8507 &operation))
8508 return NULL;
8509 Py_BEGIN_ALLOW_THREADS
8510 rc = ShellExecute((HWND)0, operation, filepath,
8511 NULL, NULL, SW_SHOWNORMAL);
8512 Py_END_ALLOW_THREADS
8513 if (rc <= (HINSTANCE)32) {
8514 PyObject *errval = win32_error("startfile", filepath);
8515 PyMem_Free(filepath);
8516 return errval;
8517 }
8518 PyMem_Free(filepath);
8519 Py_INCREF(Py_None);
8520 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008521}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008522#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008523
Martin v. Löwis438b5342002-12-27 10:16:42 +00008524#ifdef HAVE_GETLOADAVG
8525PyDoc_STRVAR(posix_getloadavg__doc__,
8526"getloadavg() -> (float, float, float)\n\n\
8527Return the number of processes in the system run queue averaged over\n\
8528the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8529was unobtainable");
8530
8531static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008532posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008533{
8534 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008535 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008536 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8537 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008538 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008539 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008540}
8541#endif
8542
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008543PyDoc_STRVAR(posix_urandom__doc__,
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008544"urandom(n) -> str\n\n\
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008545Return n random bytes suitable for cryptographic use.");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008546
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008547static PyObject *
8548posix_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008549{
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008550 Py_ssize_t size;
8551 PyObject *result;
8552 int ret;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008553
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008554 /* Read arguments */
8555 if (!PyArg_ParseTuple(args, "n:urandom", &size))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008556 return NULL;
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008557 if (size < 0)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008558 return PyErr_Format(PyExc_ValueError,
8559 "negative argument not allowed");
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008560 result = PyBytes_FromStringAndSize(NULL, size);
8561 if (result == NULL)
8562 return NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008563
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008564 ret = _PyOS_URandom(PyBytes_AS_STRING(result),
8565 PyBytes_GET_SIZE(result));
8566 if (ret == -1) {
8567 Py_DECREF(result);
8568 return NULL;
Victor Stinnerd6f85422010-05-05 23:33:33 +00008569 }
8570 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008571}
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008572
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008573#ifdef HAVE_SETRESUID
8574PyDoc_STRVAR(posix_setresuid__doc__,
8575"setresuid(ruid, euid, suid)\n\n\
8576Set the current process's real, effective, and saved user ids.");
8577
8578static PyObject*
8579posix_setresuid (PyObject *self, PyObject *args)
8580{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008581 /* We assume uid_t is no larger than a long. */
8582 long ruid, euid, suid;
8583 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8584 return NULL;
8585 if (setresuid(ruid, euid, suid) < 0)
8586 return posix_error();
8587 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008588}
8589#endif
8590
8591#ifdef HAVE_SETRESGID
8592PyDoc_STRVAR(posix_setresgid__doc__,
8593"setresgid(rgid, egid, sgid)\n\n\
8594Set the current process's real, effective, and saved group ids.");
8595
8596static PyObject*
8597posix_setresgid (PyObject *self, PyObject *args)
8598{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008599 /* We assume uid_t is no larger than a long. */
8600 long rgid, egid, sgid;
8601 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8602 return NULL;
8603 if (setresgid(rgid, egid, sgid) < 0)
8604 return posix_error();
8605 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008606}
8607#endif
8608
8609#ifdef HAVE_GETRESUID
8610PyDoc_STRVAR(posix_getresuid__doc__,
8611"getresuid() -> (ruid, euid, suid)\n\n\
8612Get tuple of the current process's real, effective, and saved user ids.");
8613
8614static PyObject*
8615posix_getresuid (PyObject *self, PyObject *noargs)
8616{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008617 uid_t ruid, euid, suid;
8618 long l_ruid, l_euid, l_suid;
8619 if (getresuid(&ruid, &euid, &suid) < 0)
8620 return posix_error();
8621 /* Force the values into long's as we don't know the size of uid_t. */
8622 l_ruid = ruid;
8623 l_euid = euid;
8624 l_suid = suid;
8625 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008626}
8627#endif
8628
8629#ifdef HAVE_GETRESGID
8630PyDoc_STRVAR(posix_getresgid__doc__,
8631"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008632Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008633
8634static PyObject*
8635posix_getresgid (PyObject *self, PyObject *noargs)
8636{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008637 uid_t rgid, egid, sgid;
8638 long l_rgid, l_egid, l_sgid;
8639 if (getresgid(&rgid, &egid, &sgid) < 0)
8640 return posix_error();
8641 /* Force the values into long's as we don't know the size of uid_t. */
8642 l_rgid = rgid;
8643 l_egid = egid;
8644 l_sgid = sgid;
8645 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008646}
8647#endif
8648
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008649static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008650 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008651#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008652 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008653#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008654 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008655#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008656 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008657#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008658 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008659#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008660 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008661#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008662#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008663 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008664#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008665#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008666 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008667#endif /* HAVE_LCHMOD */
8668#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008669 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008670#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008671#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008672 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008673#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008674#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008675 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008676#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008677#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008678 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008679#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008680#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008681 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008682#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008683#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008684 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008685#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008686 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008687#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008688#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008689#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008690 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008691#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008692 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8693 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8694 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008695#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008696 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008697#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008698#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008699 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008700#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008701 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8702 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8703 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8704 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008705#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008706 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008707#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008708#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008709 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008710#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008711 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008712#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008713 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008714#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008715 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8716 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8717 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008718#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008719 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008720#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008721 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008722#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008723 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8724 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008725#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008726#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008727 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8728 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008729#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008730 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8731 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008732#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008733#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008734#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008735 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008736#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008737#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008738 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008739#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008740#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008741 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008742#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008743#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008744 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008745#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008746#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008747 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008748#endif /* HAVE_GETEGID */
8749#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008750 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008751#endif /* HAVE_GETEUID */
8752#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008753 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008754#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008755#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008756 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008757#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008758 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008759#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008760 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008761#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008762#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008763 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008764#endif /* HAVE_GETPPID */
8765#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008766 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008767#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008768#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008769 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008770#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008771#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008772 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008773#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008774#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008775 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008776#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008777#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008778 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008779#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008780#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008781 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008782#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008783 {"popen2", win32_popen2, METH_VARARGS},
8784 {"popen3", win32_popen3, METH_VARARGS},
8785 {"popen4", win32_popen4, METH_VARARGS},
8786 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8787 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008788#else
8789#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008790 {"popen2", os2emx_popen2, METH_VARARGS},
8791 {"popen3", os2emx_popen3, METH_VARARGS},
8792 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008793#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008794#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008795#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008796#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008797 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008798#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008799#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008800 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008801#endif /* HAVE_SETEUID */
8802#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008803 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008804#endif /* HAVE_SETEGID */
8805#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008806 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008807#endif /* HAVE_SETREUID */
8808#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008809 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008810#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008811#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008812 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008813#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008814#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008815 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008816#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008817#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008818 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008819#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008820#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008821 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008822#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008823#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008824 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008825#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008826#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008828#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008829#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008830 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008831#endif /* HAVE_WAIT3 */
8832#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008834#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008835#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008837#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008838#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008839 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008840#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008841#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008842 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008843#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008844#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008845 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008846#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008847#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008848 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008849#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008850#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008852#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008853 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8854 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8855 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8856 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8857 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8858 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8859 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8860 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8861 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8862 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8863 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008864#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008866#endif
8867#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008869#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008870#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008871 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008872#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008873#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008874 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8875 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8876 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008877#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008878#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008879 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008880#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008881#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008883#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008884#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008885 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008886#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008887 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008888#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008889 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008890#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008891#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008893#endif
8894#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008896#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008897#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008898#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008899 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008900#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008901#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008902 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008903#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008904#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008905 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008906#endif /* WIFSTOPPED */
8907#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008908 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008909#endif /* WIFSIGNALED */
8910#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008911 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008912#endif /* WIFEXITED */
8913#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008914 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008915#endif /* WEXITSTATUS */
8916#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008917 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008918#endif /* WTERMSIG */
8919#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008920 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008921#endif /* WSTOPSIG */
8922#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008923#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008925#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008926#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008927 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008928#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008929#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008930 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008931#endif
8932#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008933 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008934#endif
8935#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008936 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008937#endif
Fred Drakec9680921999-12-13 16:37:25 +00008938#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008939 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008940#endif
8941#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008942 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008943#endif
8944#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008945 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008946#endif
8947#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008949#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008950 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008951#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05008953 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00008954#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008955#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008956 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008957#endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008958#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008959 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008960#endif
8961#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008962 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008963#endif
8964#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008965 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008966#endif
8967#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008968 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008969#endif
Barry Warsaw1e13eb02012-02-20 20:42:21 -05008970 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__},
Victor Stinnerd6f85422010-05-05 23:33:33 +00008971 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008972};
8973
8974
Barry Warsaw4a342091996-12-19 23:50:02 +00008975static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008976ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008977{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008978 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008979}
8980
Guido van Rossumd48f2521997-12-05 22:19:34 +00008981#if defined(PYOS_OS2)
8982/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008983static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008984{
8985 APIRET rc;
8986 ULONG values[QSV_MAX+1];
8987 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008988 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008989
8990 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008991 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008992 Py_END_ALLOW_THREADS
8993
8994 if (rc != NO_ERROR) {
8995 os2_error(rc);
8996 return -1;
8997 }
8998
Fred Drake4d1e64b2002-04-15 19:40:07 +00008999 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9000 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9001 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9002 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9003 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9004 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9005 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009006
9007 switch (values[QSV_VERSION_MINOR]) {
9008 case 0: ver = "2.00"; break;
9009 case 10: ver = "2.10"; break;
9010 case 11: ver = "2.11"; break;
9011 case 30: ver = "3.00"; break;
9012 case 40: ver = "4.00"; break;
9013 case 50: ver = "5.00"; break;
9014 default:
Tim Peters885d4572001-11-28 20:27:42 +00009015 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009016 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009017 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009018 ver = &tmp[0];
9019 }
9020
9021 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009022 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009023 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009024
9025 /* Add Indicator of Which Drive was Used to Boot the System */
9026 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9027 tmp[1] = ':';
9028 tmp[2] = '\0';
9029
Fred Drake4d1e64b2002-04-15 19:40:07 +00009030 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009031}
9032#endif
9033
Barry Warsaw4a342091996-12-19 23:50:02 +00009034static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009035all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009036{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009037#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009038 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009039#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009040#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009041 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009042#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009043#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009044 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009045#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009046#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009047 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009048#endif
Fred Drakec9680921999-12-13 16:37:25 +00009049#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009050 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009051#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009052#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009053 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009054#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009055#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009056 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009057#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009058#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009059 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009060#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009061#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009062 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009063#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009064#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009066#endif
9067#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009069#endif
9070#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009071 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009072#endif
9073#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009074 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009075#endif
9076#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009077 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009078#endif
9079#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009080 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009081#endif
9082#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009083 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009084#endif
9085#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009086 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009087#endif
9088#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009090#endif
9091#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009092 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009093#endif
9094#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009095 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009096#endif
9097#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009098 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009099#endif
9100#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009101 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009102#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009103#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009104 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009105#endif
9106#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009107 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009108#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009109#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009110 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009111#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009112#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009113 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009114#endif
9115#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009117#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009118
Tim Peters5aa91602002-01-30 05:46:57 +00009119/* MS Windows */
9120#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 /* Don't inherit in child processes. */
9122 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009123#endif
9124#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 /* Optimize for short life (keep in memory). */
9126 /* MS forgot to define this one with a non-underscore form too. */
9127 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009128#endif
9129#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 /* Automatically delete when last handle is closed. */
9131 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009132#endif
9133#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009134 /* Optimize for random access. */
9135 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009136#endif
9137#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 /* Optimize for sequential access. */
9139 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009140#endif
9141
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009142/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009143#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 /* Send a SIGIO signal whenever input or output
9145 becomes available on file descriptor */
9146 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009147#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009148#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009149 /* Direct disk access. */
9150 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009151#endif
9152#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009153 /* Must be a directory. */
9154 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009155#endif
9156#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009157 /* Do not follow links. */
9158 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009159#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009160#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009161 /* Do not update the access time. */
9162 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009163#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009164
Victor Stinnerd6f85422010-05-05 23:33:33 +00009165 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009166#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009167 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009168#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009169#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009170 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009171#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009172#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009173 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009174#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009175#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009176 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009177#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009178#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009179 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009180#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009181#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009182 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009183#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009184#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009185 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009186#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009187#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009188 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009189#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009190#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009191 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009192#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009193#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009194 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009195#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009196#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009197 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009198#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009199#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009200 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009201#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009202#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009203 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009204#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009205#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009206 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009207#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009208#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009209 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009210#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009211#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009212 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009213#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009214#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009215 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009216#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009217
Guido van Rossum246bc171999-02-01 23:54:31 +00009218#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009219#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009220 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9221 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9222 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9223 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9224 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9225 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9226 if (ins(d, "P_PM", (long)P_PM)) return -1;
9227 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9228 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9229 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9230 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9231 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9232 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9233 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9234 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9235 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9236 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9237 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9238 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9239 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009240#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9242 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9243 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9244 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9245 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009246#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009247#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009248
Guido van Rossumd48f2521997-12-05 22:19:34 +00009249#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009250 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009251#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009253}
9254
9255
Tim Peters5aa91602002-01-30 05:46:57 +00009256#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009257#define INITFUNC initnt
9258#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009259
9260#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009261#define INITFUNC initos2
9262#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009263
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009264#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009265#define INITFUNC initposix
9266#define MODNAME "posix"
9267#endif
9268
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009269PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009270INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009271{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009272 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009273
Victor Stinnerd6f85422010-05-05 23:33:33 +00009274 m = Py_InitModule3(MODNAME,
9275 posix_methods,
9276 posix__doc__);
9277 if (m == NULL)
9278 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009279
Victor Stinnerd6f85422010-05-05 23:33:33 +00009280 /* Initialize environ dictionary */
9281 v = convertenviron();
9282 Py_XINCREF(v);
9283 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9284 return;
9285 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009286
Victor Stinnerd6f85422010-05-05 23:33:33 +00009287 if (all_ins(m))
9288 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009289
Victor Stinnerd6f85422010-05-05 23:33:33 +00009290 if (setup_confname_tables(m))
9291 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009292
Victor Stinnerd6f85422010-05-05 23:33:33 +00009293 Py_INCREF(PyExc_OSError);
9294 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009295
Guido van Rossumb3d39562000-01-31 18:41:26 +00009296#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009297 if (posix_putenv_garbage == NULL)
9298 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009299#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009300
Victor Stinnerd6f85422010-05-05 23:33:33 +00009301 if (!initialized) {
9302 stat_result_desc.name = MODNAME ".stat_result";
9303 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9304 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9305 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9306 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9307 structseq_new = StatResultType.tp_new;
9308 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009309
Victor Stinnerd6f85422010-05-05 23:33:33 +00009310 statvfs_result_desc.name = MODNAME ".statvfs_result";
9311 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009312#ifdef NEED_TICKS_PER_SECOND
9313# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009314 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009315# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009316 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009317# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009318 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009319# endif
9320#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009321 }
9322 Py_INCREF((PyObject*) &StatResultType);
9323 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9324 Py_INCREF((PyObject*) &StatVFSResultType);
9325 PyModule_AddObject(m, "statvfs_result",
9326 (PyObject*) &StatVFSResultType);
9327 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009328
9329#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 /*
9331 * Step 2 of weak-linking support on Mac OS X.
9332 *
9333 * The code below removes functions that are not available on the
9334 * currently active platform.
9335 *
9336 * This block allow one to use a python binary that was build on
9337 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9338 * OSX 10.4.
9339 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009340#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009341 if (fstatvfs == NULL) {
9342 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9343 return;
9344 }
9345 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009346#endif /* HAVE_FSTATVFS */
9347
9348#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009349 if (statvfs == NULL) {
9350 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9351 return;
9352 }
9353 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009354#endif /* HAVE_STATVFS */
9355
9356# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009357 if (lchown == NULL) {
9358 if (PyObject_DelAttrString(m, "lchown") == -1) {
9359 return;
9360 }
9361 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009362#endif /* HAVE_LCHOWN */
9363
9364
9365#endif /* __APPLE__ */
9366
Guido van Rossumb6775db1994-08-01 11:34:53 +00009367}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009368
9369#ifdef __cplusplus
9370}
9371#endif
9372
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009373