blob: 1040ec5b40480bd35f54705c412e82b5c3905113 [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
Stefan Krah182ae642010-07-13 19:17:08 +00001959#if (defined(__sun) && defined(__SVR4)) || defined(__OpenBSD__)
1960/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
1961static PyObject *
1962posix_getcwd(PyObject *self, PyObject *noargs)
1963{
1964 char buf[PATH_MAX+2];
1965 char *res;
1966
1967 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00001968 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00001969 Py_END_ALLOW_THREADS
1970
1971 if (res == NULL)
1972 return posix_error();
1973
1974 return PyString_FromString(buf);
1975}
1976#else
Barry Warsaw53699e91996-12-10 23:23:01 +00001977static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001978posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001979{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001980 int bufsize_incr = 1024;
1981 int bufsize = 0;
1982 char *tmpbuf = NULL;
1983 char *res = NULL;
1984 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001985
Victor Stinnerd6f85422010-05-05 23:33:33 +00001986 Py_BEGIN_ALLOW_THREADS
1987 do {
1988 bufsize = bufsize + bufsize_incr;
1989 tmpbuf = malloc(bufsize);
1990 if (tmpbuf == NULL) {
1991 break;
1992 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001993#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001994 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001995#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001996 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001997#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001998
Victor Stinnerd6f85422010-05-05 23:33:33 +00001999 if (res == NULL) {
2000 free(tmpbuf);
2001 }
2002 } while ((res == NULL) && (errno == ERANGE));
2003 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002004
Victor Stinnerd6f85422010-05-05 23:33:33 +00002005 if (res == NULL)
2006 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002007
Victor Stinnerd6f85422010-05-05 23:33:33 +00002008 dynamic_return = PyString_FromString(tmpbuf);
2009 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002010
Victor Stinnerd6f85422010-05-05 23:33:33 +00002011 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002012}
Stefan Krah182ae642010-07-13 19:17:08 +00002013#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002014
Walter Dörwald3b918c32002-11-21 20:18:46 +00002015#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002016PyDoc_STRVAR(posix_getcwdu__doc__,
2017"getcwdu() -> path\n\n\
2018Return a unicode string representing the current working directory.");
2019
2020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002021posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002023 char buf[1026];
2024 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002025
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002026#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002027 DWORD len;
2028 wchar_t wbuf[1026];
2029 wchar_t *wbuf2 = wbuf;
2030 PyObject *resobj;
2031 Py_BEGIN_ALLOW_THREADS
2032 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2033 /* If the buffer is large enough, len does not include the
2034 terminating \0. If the buffer is too small, len includes
2035 the space needed for the terminator. */
2036 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2037 wbuf2 = malloc(len * sizeof(wchar_t));
2038 if (wbuf2)
2039 len = GetCurrentDirectoryW(len, wbuf2);
2040 }
2041 Py_END_ALLOW_THREADS
2042 if (!wbuf2) {
2043 PyErr_NoMemory();
2044 return NULL;
2045 }
2046 if (!len) {
2047 if (wbuf2 != wbuf) free(wbuf2);
2048 return win32_error("getcwdu", NULL);
2049 }
2050 resobj = PyUnicode_FromWideChar(wbuf2, len);
2051 if (wbuf2 != wbuf) free(wbuf2);
2052 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002053#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002054
Victor Stinnerd6f85422010-05-05 23:33:33 +00002055 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002056#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002057 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002058#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002059 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002060#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002061 Py_END_ALLOW_THREADS
2062 if (res == NULL)
2063 return posix_error();
2064 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002065}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002066#endif /* Py_USING_UNICODE */
2067#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002069
Guido van Rossumb6775db1994-08-01 11:34:53 +00002070#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002072"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Barry Warsaw53699e91996-12-10 23:23:01 +00002075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002076posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002077{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002078 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002083PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002084"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085Return a list containing the names of the entries in the directory.\n\
2086\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002087 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002088\n\
2089The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Barry Warsaw53699e91996-12-10 23:23:01 +00002092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002093posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002095 /* XXX Should redo this putting the (now four) versions of opendir
2096 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002097#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002098
Victor Stinnerd6f85422010-05-05 23:33:33 +00002099 PyObject *d, *v;
2100 HANDLE hFindFile;
2101 BOOL result;
2102 WIN32_FIND_DATA FileData;
2103 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2104 char *bufptr = namebuf;
2105 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106
Victor Stinnerd6f85422010-05-05 23:33:33 +00002107 PyObject *po;
2108 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2109 WIN32_FIND_DATAW wFileData;
2110 Py_UNICODE *wnamebuf;
2111 /* Overallocate for \\*.*\0 */
2112 len = PyUnicode_GET_SIZE(po);
2113 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2114 if (!wnamebuf) {
2115 PyErr_NoMemory();
2116 return NULL;
2117 }
2118 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2119 if (len > 0) {
2120 Py_UNICODE wch = wnamebuf[len-1];
2121 if (wch != L'/' && wch != L'\\' && wch != L':')
2122 wnamebuf[len++] = L'\\';
2123 wcscpy(wnamebuf + len, L"*.*");
2124 }
2125 if ((d = PyList_New(0)) == NULL) {
2126 free(wnamebuf);
2127 return NULL;
2128 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002129 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002130 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002131 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002132 if (hFindFile == INVALID_HANDLE_VALUE) {
2133 int error = GetLastError();
2134 if (error == ERROR_FILE_NOT_FOUND) {
2135 free(wnamebuf);
2136 return d;
2137 }
2138 Py_DECREF(d);
2139 win32_error_unicode("FindFirstFileW", wnamebuf);
2140 free(wnamebuf);
2141 return NULL;
2142 }
2143 do {
2144 /* Skip over . and .. */
2145 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2146 wcscmp(wFileData.cFileName, L"..") != 0) {
2147 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2148 if (v == NULL) {
2149 Py_DECREF(d);
2150 d = NULL;
2151 break;
2152 }
2153 if (PyList_Append(d, v) != 0) {
2154 Py_DECREF(v);
2155 Py_DECREF(d);
2156 d = NULL;
2157 break;
2158 }
2159 Py_DECREF(v);
2160 }
2161 Py_BEGIN_ALLOW_THREADS
2162 result = FindNextFileW(hFindFile, &wFileData);
2163 Py_END_ALLOW_THREADS
2164 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2165 it got to the end of the directory. */
2166 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2167 Py_DECREF(d);
2168 win32_error_unicode("FindNextFileW", wnamebuf);
2169 FindClose(hFindFile);
2170 free(wnamebuf);
2171 return NULL;
2172 }
2173 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002174
Victor Stinnerd6f85422010-05-05 23:33:33 +00002175 if (FindClose(hFindFile) == FALSE) {
2176 Py_DECREF(d);
2177 win32_error_unicode("FindClose", wnamebuf);
2178 free(wnamebuf);
2179 return NULL;
2180 }
2181 free(wnamebuf);
2182 return d;
2183 }
2184 /* Drop the argument parsing error as narrow strings
2185 are also valid. */
2186 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187
Victor Stinnerd6f85422010-05-05 23:33:33 +00002188 if (!PyArg_ParseTuple(args, "et#:listdir",
2189 Py_FileSystemDefaultEncoding, &bufptr, &len))
2190 return NULL;
2191 if (len > 0) {
2192 char ch = namebuf[len-1];
2193 if (ch != SEP && ch != ALTSEP && ch != ':')
2194 namebuf[len++] = '/';
2195 strcpy(namebuf + len, "*.*");
2196 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002197
Victor Stinnerd6f85422010-05-05 23:33:33 +00002198 if ((d = PyList_New(0)) == NULL)
2199 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002200
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002201 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002202 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002203 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 if (hFindFile == INVALID_HANDLE_VALUE) {
2205 int error = GetLastError();
2206 if (error == ERROR_FILE_NOT_FOUND)
2207 return d;
2208 Py_DECREF(d);
2209 return win32_error("FindFirstFile", namebuf);
2210 }
2211 do {
2212 /* Skip over . and .. */
2213 if (strcmp(FileData.cFileName, ".") != 0 &&
2214 strcmp(FileData.cFileName, "..") != 0) {
2215 v = PyString_FromString(FileData.cFileName);
2216 if (v == NULL) {
2217 Py_DECREF(d);
2218 d = NULL;
2219 break;
2220 }
2221 if (PyList_Append(d, v) != 0) {
2222 Py_DECREF(v);
2223 Py_DECREF(d);
2224 d = NULL;
2225 break;
2226 }
2227 Py_DECREF(v);
2228 }
2229 Py_BEGIN_ALLOW_THREADS
2230 result = FindNextFile(hFindFile, &FileData);
2231 Py_END_ALLOW_THREADS
2232 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2233 it got to the end of the directory. */
2234 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2235 Py_DECREF(d);
2236 win32_error("FindNextFile", namebuf);
2237 FindClose(hFindFile);
2238 return NULL;
2239 }
2240 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002241
Victor Stinnerd6f85422010-05-05 23:33:33 +00002242 if (FindClose(hFindFile) == FALSE) {
2243 Py_DECREF(d);
2244 return win32_error("FindClose", namebuf);
2245 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002246
Victor Stinnerd6f85422010-05-05 23:33:33 +00002247 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002248
Tim Peters0bb44a42000-09-15 07:44:49 +00002249#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002250
2251#ifndef MAX_PATH
2252#define MAX_PATH CCHMAXPATH
2253#endif
2254 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002255 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002256 PyObject *d, *v;
2257 char namebuf[MAX_PATH+5];
2258 HDIR hdir = 1;
2259 ULONG srchcnt = 1;
2260 FILEFINDBUF3 ep;
2261 APIRET rc;
2262
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002263 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002264 return NULL;
2265 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002266 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267 return NULL;
2268 }
2269 strcpy(namebuf, name);
2270 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002271 if (*pt == ALTSEP)
2272 *pt = SEP;
2273 if (namebuf[len-1] != SEP)
2274 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002275 strcpy(namebuf + len, "*.*");
2276
Victor Stinnerd6f85422010-05-05 23:33:33 +00002277 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278 return NULL;
2279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2281 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002283 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2284 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2285 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286
2287 if (rc != NO_ERROR) {
2288 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002289 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290 }
2291
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002293 do {
2294 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002295 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002296 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297
2298 strcpy(namebuf, ep.achName);
2299
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002300 /* Leave Case of Name Alone -- In Native Form */
2301 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002303 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304 if (v == NULL) {
2305 Py_DECREF(d);
2306 d = NULL;
2307 break;
2308 }
2309 if (PyList_Append(d, v) != 0) {
2310 Py_DECREF(v);
2311 Py_DECREF(d);
2312 d = NULL;
2313 break;
2314 }
2315 Py_DECREF(v);
2316 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2317 }
2318
2319 return d;
2320#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002321
Victor Stinnerd6f85422010-05-05 23:33:33 +00002322 char *name = NULL;
2323 PyObject *d, *v;
2324 DIR *dirp;
2325 struct dirent *ep;
2326 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002327
Victor Stinnerd6f85422010-05-05 23:33:33 +00002328 errno = 0;
2329 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2330 arg_is_unicode = 0;
2331 PyErr_Clear();
2332 }
2333 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2334 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002335 Py_BEGIN_ALLOW_THREADS
2336 dirp = opendir(name);
2337 Py_END_ALLOW_THREADS
2338 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002339 return posix_error_with_allocated_filename(name);
2340 }
2341 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002342 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002343 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002344 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002345 PyMem_Free(name);
2346 return NULL;
2347 }
2348 for (;;) {
2349 errno = 0;
2350 Py_BEGIN_ALLOW_THREADS
2351 ep = readdir(dirp);
2352 Py_END_ALLOW_THREADS
2353 if (ep == NULL) {
2354 if (errno == 0) {
2355 break;
2356 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002357 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002358 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002359 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002360 Py_DECREF(d);
2361 return posix_error_with_allocated_filename(name);
2362 }
2363 }
2364 if (ep->d_name[0] == '.' &&
2365 (NAMLEN(ep) == 1 ||
2366 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2367 continue;
2368 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2369 if (v == NULL) {
2370 Py_DECREF(d);
2371 d = NULL;
2372 break;
2373 }
Just van Rossum46c97842003-02-25 21:42:15 +00002374#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002375 if (arg_is_unicode) {
2376 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002377
Victor Stinnerd6f85422010-05-05 23:33:33 +00002378 w = PyUnicode_FromEncodedObject(v,
2379 Py_FileSystemDefaultEncoding,
2380 "strict");
2381 if (w != NULL) {
2382 Py_DECREF(v);
2383 v = w;
2384 }
2385 else {
2386 /* fall back to the original byte string, as
2387 discussed in patch #683592 */
2388 PyErr_Clear();
2389 }
2390 }
Just van Rossum46c97842003-02-25 21:42:15 +00002391#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002392 if (PyList_Append(d, v) != 0) {
2393 Py_DECREF(v);
2394 Py_DECREF(d);
2395 d = NULL;
2396 break;
2397 }
2398 Py_DECREF(v);
2399 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002400 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002401 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002402 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002403 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002404
Victor Stinnerd6f85422010-05-05 23:33:33 +00002405 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002406
Tim Peters0bb44a42000-09-15 07:44:49 +00002407#endif /* which OS */
2408} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002409
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002410#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002411/* A helper function for abspath on win32 */
2412static PyObject *
2413posix__getfullpathname(PyObject *self, PyObject *args)
2414{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002415 /* assume encoded strings won't more than double no of chars */
2416 char inbuf[MAX_PATH*2];
2417 char *inbufp = inbuf;
2418 Py_ssize_t insize = sizeof(inbuf);
2419 char outbuf[MAX_PATH*2];
2420 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002421
Victor Stinnerd6f85422010-05-05 23:33:33 +00002422 PyUnicodeObject *po;
2423 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2424 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2425 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2426 Py_UNICODE *wtemp;
2427 DWORD result;
2428 PyObject *v;
2429 result = GetFullPathNameW(wpath,
2430 sizeof(woutbuf)/sizeof(woutbuf[0]),
2431 woutbuf, &wtemp);
2432 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2433 woutbufp = malloc(result * sizeof(Py_UNICODE));
2434 if (!woutbufp)
2435 return PyErr_NoMemory();
2436 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2437 }
2438 if (result)
2439 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2440 else
2441 v = win32_error_unicode("GetFullPathNameW", wpath);
2442 if (woutbufp != woutbuf)
2443 free(woutbufp);
2444 return v;
2445 }
2446 /* Drop the argument parsing error as narrow strings
2447 are also valid. */
2448 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002449
Victor Stinnerd6f85422010-05-05 23:33:33 +00002450 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2451 Py_FileSystemDefaultEncoding, &inbufp,
2452 &insize))
2453 return NULL;
2454 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2455 outbuf, &temp))
2456 return win32_error("GetFullPathName", inbuf);
2457 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2458 return PyUnicode_Decode(outbuf, strlen(outbuf),
2459 Py_FileSystemDefaultEncoding, NULL);
2460 }
2461 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002462} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002463#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002464
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002465PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002466"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002467Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002468
Barry Warsaw53699e91996-12-10 23:23:01 +00002469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002470posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002471{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002472 int res;
2473 char *path = NULL;
2474 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002475
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002476#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002477 PyUnicodeObject *po;
2478 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2479 Py_BEGIN_ALLOW_THREADS
2480 /* PyUnicode_AS_UNICODE OK without thread lock as
2481 it is a simple dereference. */
2482 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2483 Py_END_ALLOW_THREADS
2484 if (!res)
2485 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2486 Py_INCREF(Py_None);
2487 return Py_None;
2488 }
2489 /* Drop the argument parsing error as narrow strings
2490 are also valid. */
2491 PyErr_Clear();
2492 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2493 Py_FileSystemDefaultEncoding, &path, &mode))
2494 return NULL;
2495 Py_BEGIN_ALLOW_THREADS
2496 /* PyUnicode_AS_UNICODE OK without thread lock as
2497 it is a simple dereference. */
2498 res = CreateDirectoryA(path, NULL);
2499 Py_END_ALLOW_THREADS
2500 if (!res) {
2501 win32_error("mkdir", path);
2502 PyMem_Free(path);
2503 return NULL;
2504 }
2505 PyMem_Free(path);
2506 Py_INCREF(Py_None);
2507 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002508#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002509
Victor Stinnerd6f85422010-05-05 23:33:33 +00002510 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2511 Py_FileSystemDefaultEncoding, &path, &mode))
2512 return NULL;
2513 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002514#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002515 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002516#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002518#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002519 Py_END_ALLOW_THREADS
2520 if (res < 0)
2521 return posix_error_with_allocated_filename(path);
2522 PyMem_Free(path);
2523 Py_INCREF(Py_None);
2524 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002525#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002526}
2527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002528
Neal Norwitz1818ed72006-03-26 00:29:48 +00002529/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2530#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002531#include <sys/resource.h>
2532#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002533
Neal Norwitz1818ed72006-03-26 00:29:48 +00002534
2535#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002537"nice(inc) -> new_priority\n\n\
2538Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002542{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002543 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002544
Victor Stinnerd6f85422010-05-05 23:33:33 +00002545 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2546 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002547
Victor Stinnerd6f85422010-05-05 23:33:33 +00002548 /* There are two flavours of 'nice': one that returns the new
2549 priority (as required by almost all standards out there) and the
2550 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2551 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002552
Victor Stinnerd6f85422010-05-05 23:33:33 +00002553 If we are of the nice family that returns the new priority, we
2554 need to clear errno before the call, and check if errno is filled
2555 before calling posix_error() on a returnvalue of -1, because the
2556 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002557
Victor Stinnerd6f85422010-05-05 23:33:33 +00002558 errno = 0;
2559 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002560#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002561 if (value == 0)
2562 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002563#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002564 if (value == -1 && errno != 0)
2565 /* either nice() or getpriority() returned an error */
2566 return posix_error();
2567 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002568}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002569#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002571PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002572"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002573Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002574
Barry Warsaw53699e91996-12-10 23:23:01 +00002575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002576posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002577{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002578#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002579 PyObject *o1, *o2;
2580 char *p1, *p2;
2581 BOOL result;
2582 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2583 goto error;
2584 if (!convert_to_unicode(&o1))
2585 goto error;
2586 if (!convert_to_unicode(&o2)) {
2587 Py_DECREF(o1);
2588 goto error;
2589 }
2590 Py_BEGIN_ALLOW_THREADS
2591 result = MoveFileW(PyUnicode_AsUnicode(o1),
2592 PyUnicode_AsUnicode(o2));
2593 Py_END_ALLOW_THREADS
2594 Py_DECREF(o1);
2595 Py_DECREF(o2);
2596 if (!result)
2597 return win32_error("rename", NULL);
2598 Py_INCREF(Py_None);
2599 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002600error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002601 PyErr_Clear();
2602 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2603 return NULL;
2604 Py_BEGIN_ALLOW_THREADS
2605 result = MoveFileA(p1, p2);
2606 Py_END_ALLOW_THREADS
2607 if (!result)
2608 return win32_error("rename", NULL);
2609 Py_INCREF(Py_None);
2610 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002611#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002612 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002613#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002614}
2615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002617PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002618"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002619Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002620
Barry Warsaw53699e91996-12-10 23:23:01 +00002621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002622posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002624#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002625 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002627 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002628#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002629}
2630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002633"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Barry Warsaw53699e91996-12-10 23:23:01 +00002636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002637posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002640 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002642 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002643#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644}
2645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002646
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002647#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002648PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002649"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002651
Barry Warsaw53699e91996-12-10 23:23:01 +00002652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002653posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002654{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002655 char *command;
2656 long sts;
2657 if (!PyArg_ParseTuple(args, "s:system", &command))
2658 return NULL;
2659 Py_BEGIN_ALLOW_THREADS
2660 sts = system(command);
2661 Py_END_ALLOW_THREADS
2662 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002663}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002664#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002668"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Barry Warsaw53699e91996-12-10 23:23:01 +00002671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002672posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002673{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002674 int i;
2675 if (!PyArg_ParseTuple(args, "i:umask", &i))
2676 return NULL;
2677 i = (int)umask(i);
2678 if (i < 0)
2679 return posix_error();
2680 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002681}
2682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002684PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002685"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002688PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002689"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002690Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002691
Barry Warsaw53699e91996-12-10 23:23:01 +00002692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002693posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002694{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002695#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002696 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002698 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002699#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002700}
2701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002702
Guido van Rossumb6775db1994-08-01 11:34:53 +00002703#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002705"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707
Barry Warsaw53699e91996-12-10 23:23:01 +00002708static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002709posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002710{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002711 struct utsname u;
2712 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002713
Victor Stinnerd6f85422010-05-05 23:33:33 +00002714 Py_BEGIN_ALLOW_THREADS
2715 res = uname(&u);
2716 Py_END_ALLOW_THREADS
2717 if (res < 0)
2718 return posix_error();
2719 return Py_BuildValue("(sssss)",
2720 u.sysname,
2721 u.nodename,
2722 u.release,
2723 u.version,
2724 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002725}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002726#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002727
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002728static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002729extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002730{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002731 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002732 if (PyFloat_Check(t)) {
2733 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002734 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002735 if (!intobj)
2736 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002737#if SIZEOF_TIME_T > SIZEOF_LONG
2738 intval = PyInt_AsUnsignedLongLongMask(intobj);
2739#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002740 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002741#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 Py_DECREF(intobj);
2743 if (intval == -1 && PyErr_Occurred())
2744 return -1;
2745 *sec = intval;
2746 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2747 if (*usec < 0)
2748 /* If rounding gave us a negative number,
2749 truncate. */
2750 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002751 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002752 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002753#if SIZEOF_TIME_T > SIZEOF_LONG
2754 intval = PyInt_AsUnsignedLongLongMask(t);
2755#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002756 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002757#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002758 if (intval == -1 && PyErr_Occurred())
2759 return -1;
2760 *sec = intval;
2761 *usec = 0;
2762 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002763}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002765PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002766"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002767utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002768Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Barry Warsaw53699e91996-12-10 23:23:01 +00002771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002772posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002773{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002774#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002775 PyObject *arg;
2776 PyUnicodeObject *obwpath;
2777 wchar_t *wpath = NULL;
2778 char *apath = NULL;
2779 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002780 time_t atimesec, mtimesec;
2781 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002782 FILETIME atime, mtime;
2783 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002784
Victor Stinnerd6f85422010-05-05 23:33:33 +00002785 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2786 wpath = PyUnicode_AS_UNICODE(obwpath);
2787 Py_BEGIN_ALLOW_THREADS
2788 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2789 NULL, OPEN_EXISTING,
2790 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2791 Py_END_ALLOW_THREADS
2792 if (hFile == INVALID_HANDLE_VALUE)
2793 return win32_error_unicode("utime", wpath);
2794 } else
2795 /* Drop the argument parsing error as narrow strings
2796 are also valid. */
2797 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002798
Victor Stinnerd6f85422010-05-05 23:33:33 +00002799 if (!wpath) {
2800 if (!PyArg_ParseTuple(args, "etO:utime",
2801 Py_FileSystemDefaultEncoding, &apath, &arg))
2802 return NULL;
2803 Py_BEGIN_ALLOW_THREADS
2804 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2805 NULL, OPEN_EXISTING,
2806 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2807 Py_END_ALLOW_THREADS
2808 if (hFile == INVALID_HANDLE_VALUE) {
2809 win32_error("utime", apath);
2810 PyMem_Free(apath);
2811 return NULL;
2812 }
2813 PyMem_Free(apath);
2814 }
2815
2816 if (arg == Py_None) {
2817 SYSTEMTIME now;
2818 GetSystemTime(&now);
2819 if (!SystemTimeToFileTime(&now, &mtime) ||
2820 !SystemTimeToFileTime(&now, &atime)) {
2821 win32_error("utime", NULL);
2822 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00002823 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00002824 }
2825 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2826 PyErr_SetString(PyExc_TypeError,
2827 "utime() arg 2 must be a tuple (atime, mtime)");
2828 goto done;
2829 }
2830 else {
2831 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2832 &atimesec, &ausec) == -1)
2833 goto done;
2834 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2835 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2836 &mtimesec, &musec) == -1)
2837 goto done;
2838 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2839 }
2840 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2841 /* Avoid putting the file name into the error here,
2842 as that may confuse the user into believing that
2843 something is wrong with the file, when it also
2844 could be the time stamp that gives a problem. */
2845 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00002846 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002847 }
2848 Py_INCREF(Py_None);
2849 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002850done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002851 CloseHandle(hFile);
2852 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002853#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002854
Victor Stinnerd6f85422010-05-05 23:33:33 +00002855 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002856 time_t atime, mtime;
2857 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002858 int res;
2859 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002860
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002861#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002862 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002863#define ATIME buf[0].tv_sec
2864#define MTIME buf[1].tv_sec
2865#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002866/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002867 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002868#define ATIME buf.actime
2869#define MTIME buf.modtime
2870#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002871#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002872 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002873#define ATIME buf[0]
2874#define MTIME buf[1]
2875#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002876#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002877
Mark Hammond817c9292003-12-03 01:22:38 +00002878
Victor Stinnerd6f85422010-05-05 23:33:33 +00002879 if (!PyArg_ParseTuple(args, "etO:utime",
2880 Py_FileSystemDefaultEncoding, &path, &arg))
2881 return NULL;
2882 if (arg == Py_None) {
2883 /* optional time values not given */
2884 Py_BEGIN_ALLOW_THREADS
2885 res = utime(path, NULL);
2886 Py_END_ALLOW_THREADS
2887 }
2888 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2889 PyErr_SetString(PyExc_TypeError,
2890 "utime() arg 2 must be a tuple (atime, mtime)");
2891 PyMem_Free(path);
2892 return NULL;
2893 }
2894 else {
2895 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2896 &atime, &ausec) == -1) {
2897 PyMem_Free(path);
2898 return NULL;
2899 }
2900 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2901 &mtime, &musec) == -1) {
2902 PyMem_Free(path);
2903 return NULL;
2904 }
2905 ATIME = atime;
2906 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002907#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002908 buf[0].tv_usec = ausec;
2909 buf[1].tv_usec = musec;
2910 Py_BEGIN_ALLOW_THREADS
2911 res = utimes(path, buf);
2912 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002914 Py_BEGIN_ALLOW_THREADS
2915 res = utime(path, UTIME_ARG);
2916 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002917#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002918 }
2919 if (res < 0) {
2920 return posix_error_with_allocated_filename(path);
2921 }
2922 PyMem_Free(path);
2923 Py_INCREF(Py_None);
2924 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002925#undef UTIME_ARG
2926#undef ATIME
2927#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002928#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002929}
2930
Guido van Rossum85e3b011991-06-03 12:42:10 +00002931
Guido van Rossum3b066191991-06-04 19:40:25 +00002932/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002934PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002935"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002937
Barry Warsaw53699e91996-12-10 23:23:01 +00002938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002939posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002941 int sts;
2942 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2943 return NULL;
2944 _exit(sts);
2945 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002946}
2947
Martin v. Löwis114619e2002-10-07 06:44:21 +00002948#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2949static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002950free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002951{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002952 Py_ssize_t i;
2953 for (i = 0; i < count; i++)
2954 PyMem_Free(array[i]);
2955 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956}
2957#endif
2958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002960#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002962"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002963Execute an executable path with arguments, replacing current process.\n\
2964\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002965 path: path of executable file\n\
2966 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002967
Barry Warsaw53699e91996-12-10 23:23:01 +00002968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002969posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002970{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002971 char *path;
2972 PyObject *argv;
2973 char **argvlist;
2974 Py_ssize_t i, argc;
2975 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002976
Victor Stinnerd6f85422010-05-05 23:33:33 +00002977 /* execv has two arguments: (path, argv), where
2978 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002979
Victor Stinnerd6f85422010-05-05 23:33:33 +00002980 if (!PyArg_ParseTuple(args, "etO:execv",
2981 Py_FileSystemDefaultEncoding,
2982 &path, &argv))
2983 return NULL;
2984 if (PyList_Check(argv)) {
2985 argc = PyList_Size(argv);
2986 getitem = PyList_GetItem;
2987 }
2988 else if (PyTuple_Check(argv)) {
2989 argc = PyTuple_Size(argv);
2990 getitem = PyTuple_GetItem;
2991 }
2992 else {
2993 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2994 PyMem_Free(path);
2995 return NULL;
2996 }
2997 if (argc < 1) {
2998 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2999 PyMem_Free(path);
3000 return NULL;
3001 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003002
Victor Stinnerd6f85422010-05-05 23:33:33 +00003003 argvlist = PyMem_NEW(char *, argc+1);
3004 if (argvlist == NULL) {
3005 PyMem_Free(path);
3006 return PyErr_NoMemory();
3007 }
3008 for (i = 0; i < argc; i++) {
3009 if (!PyArg_Parse((*getitem)(argv, i), "et",
3010 Py_FileSystemDefaultEncoding,
3011 &argvlist[i])) {
3012 free_string_array(argvlist, i);
3013 PyErr_SetString(PyExc_TypeError,
3014 "execv() arg 2 must contain only strings");
3015 PyMem_Free(path);
3016 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003017
Victor Stinnerd6f85422010-05-05 23:33:33 +00003018 }
3019 }
3020 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003021
Victor Stinnerd6f85422010-05-05 23:33:33 +00003022 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003023
Victor Stinnerd6f85422010-05-05 23:33:33 +00003024 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003025
Victor Stinnerd6f85422010-05-05 23:33:33 +00003026 free_string_array(argvlist, argc);
3027 PyMem_Free(path);
3028 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003029}
3030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003032PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003033"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003034Execute a path with arguments and environment, replacing current process.\n\
3035\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003036 path: path of executable file\n\
3037 args: tuple or list of arguments\n\
3038 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Barry Warsaw53699e91996-12-10 23:23:01 +00003040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003041posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003042{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003043 char *path;
3044 PyObject *argv, *env;
3045 char **argvlist;
3046 char **envlist;
3047 PyObject *key, *val, *keys=NULL, *vals=NULL;
3048 Py_ssize_t i, pos, argc, envc;
3049 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3050 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003051
Victor Stinnerd6f85422010-05-05 23:33:33 +00003052 /* execve has three arguments: (path, argv, env), where
3053 argv is a list or tuple of strings and env is a dictionary
3054 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003055
Victor Stinnerd6f85422010-05-05 23:33:33 +00003056 if (!PyArg_ParseTuple(args, "etOO:execve",
3057 Py_FileSystemDefaultEncoding,
3058 &path, &argv, &env))
3059 return NULL;
3060 if (PyList_Check(argv)) {
3061 argc = PyList_Size(argv);
3062 getitem = PyList_GetItem;
3063 }
3064 else if (PyTuple_Check(argv)) {
3065 argc = PyTuple_Size(argv);
3066 getitem = PyTuple_GetItem;
3067 }
3068 else {
3069 PyErr_SetString(PyExc_TypeError,
3070 "execve() arg 2 must be a tuple or list");
3071 goto fail_0;
3072 }
3073 if (!PyMapping_Check(env)) {
3074 PyErr_SetString(PyExc_TypeError,
3075 "execve() arg 3 must be a mapping object");
3076 goto fail_0;
3077 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003078
Victor Stinnerd6f85422010-05-05 23:33:33 +00003079 argvlist = PyMem_NEW(char *, argc+1);
3080 if (argvlist == NULL) {
3081 PyErr_NoMemory();
3082 goto fail_0;
3083 }
3084 for (i = 0; i < argc; i++) {
3085 if (!PyArg_Parse((*getitem)(argv, i),
3086 "et;execve() arg 2 must contain only strings",
3087 Py_FileSystemDefaultEncoding,
3088 &argvlist[i]))
3089 {
3090 lastarg = i;
3091 goto fail_1;
3092 }
3093 }
3094 lastarg = argc;
3095 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096
Victor Stinnerd6f85422010-05-05 23:33:33 +00003097 i = PyMapping_Size(env);
3098 if (i < 0)
3099 goto fail_1;
3100 envlist = PyMem_NEW(char *, i + 1);
3101 if (envlist == NULL) {
3102 PyErr_NoMemory();
3103 goto fail_1;
3104 }
3105 envc = 0;
3106 keys = PyMapping_Keys(env);
3107 vals = PyMapping_Values(env);
3108 if (!keys || !vals)
3109 goto fail_2;
3110 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3111 PyErr_SetString(PyExc_TypeError,
3112 "execve(): env.keys() or env.values() is not a list");
3113 goto fail_2;
3114 }
Tim Peters5aa91602002-01-30 05:46:57 +00003115
Victor Stinnerd6f85422010-05-05 23:33:33 +00003116 for (pos = 0; pos < i; pos++) {
3117 char *p, *k, *v;
3118 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003119
Victor Stinnerd6f85422010-05-05 23:33:33 +00003120 key = PyList_GetItem(keys, pos);
3121 val = PyList_GetItem(vals, pos);
3122 if (!key || !val)
3123 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003124
Victor Stinnerd6f85422010-05-05 23:33:33 +00003125 if (!PyArg_Parse(
3126 key,
3127 "s;execve() arg 3 contains a non-string key",
3128 &k) ||
3129 !PyArg_Parse(
3130 val,
3131 "s;execve() arg 3 contains a non-string value",
3132 &v))
3133 {
3134 goto fail_2;
3135 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003136
3137#if defined(PYOS_OS2)
3138 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3139 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3140#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003141 len = PyString_Size(key) + PyString_Size(val) + 2;
3142 p = PyMem_NEW(char, len);
3143 if (p == NULL) {
3144 PyErr_NoMemory();
3145 goto fail_2;
3146 }
3147 PyOS_snprintf(p, len, "%s=%s", k, v);
3148 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003149#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003150 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003152 }
3153 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003154
Victor Stinnerd6f85422010-05-05 23:33:33 +00003155 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003156
Victor Stinnerd6f85422010-05-05 23:33:33 +00003157 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003158
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003161 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003162 while (--envc >= 0)
3163 PyMem_DEL(envlist[envc]);
3164 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003165 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003166 free_string_array(argvlist, lastarg);
3167 Py_XDECREF(vals);
3168 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003169 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003170 PyMem_Free(path);
3171 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003172}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003173#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossuma1065681999-01-25 23:20:23 +00003176#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003178"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003179Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003180\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003181 mode: mode of process creation\n\
3182 path: path of executable file\n\
3183 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003184
3185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003186posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003187{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003188 char *path;
3189 PyObject *argv;
3190 char **argvlist;
3191 int mode, i;
3192 Py_ssize_t argc;
3193 Py_intptr_t spawnval;
3194 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003195
Victor Stinnerd6f85422010-05-05 23:33:33 +00003196 /* spawnv has three arguments: (mode, path, argv), where
3197 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003198
Victor Stinnerd6f85422010-05-05 23:33:33 +00003199 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3200 Py_FileSystemDefaultEncoding,
3201 &path, &argv))
3202 return NULL;
3203 if (PyList_Check(argv)) {
3204 argc = PyList_Size(argv);
3205 getitem = PyList_GetItem;
3206 }
3207 else if (PyTuple_Check(argv)) {
3208 argc = PyTuple_Size(argv);
3209 getitem = PyTuple_GetItem;
3210 }
3211 else {
3212 PyErr_SetString(PyExc_TypeError,
3213 "spawnv() arg 2 must be a tuple or list");
3214 PyMem_Free(path);
3215 return NULL;
3216 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003217
Victor Stinnerd6f85422010-05-05 23:33:33 +00003218 argvlist = PyMem_NEW(char *, argc+1);
3219 if (argvlist == NULL) {
3220 PyMem_Free(path);
3221 return PyErr_NoMemory();
3222 }
3223 for (i = 0; i < argc; i++) {
3224 if (!PyArg_Parse((*getitem)(argv, i), "et",
3225 Py_FileSystemDefaultEncoding,
3226 &argvlist[i])) {
3227 free_string_array(argvlist, i);
3228 PyErr_SetString(
3229 PyExc_TypeError,
3230 "spawnv() arg 2 must contain only strings");
3231 PyMem_Free(path);
3232 return NULL;
3233 }
3234 }
3235 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003236
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003237#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003238 Py_BEGIN_ALLOW_THREADS
3239 spawnval = spawnv(mode, path, argvlist);
3240 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003241#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003242 if (mode == _OLD_P_OVERLAY)
3243 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003244
Victor Stinnerd6f85422010-05-05 23:33:33 +00003245 Py_BEGIN_ALLOW_THREADS
3246 spawnval = _spawnv(mode, path, argvlist);
3247 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003248#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003249
Victor Stinnerd6f85422010-05-05 23:33:33 +00003250 free_string_array(argvlist, argc);
3251 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003252
Victor Stinnerd6f85422010-05-05 23:33:33 +00003253 if (spawnval == -1)
3254 return posix_error();
3255 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003256#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003257 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003258#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003259 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003260#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003261}
3262
3263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003264PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003265"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003266Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003267\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003268 mode: mode of process creation\n\
3269 path: path of executable file\n\
3270 args: tuple or list of arguments\n\
3271 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003272
3273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003274posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003275{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003276 char *path;
3277 PyObject *argv, *env;
3278 char **argvlist;
3279 char **envlist;
3280 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3281 int mode, pos, envc;
3282 Py_ssize_t argc, i;
3283 Py_intptr_t spawnval;
3284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3285 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003286
Victor Stinnerd6f85422010-05-05 23:33:33 +00003287 /* spawnve has four arguments: (mode, path, argv, env), where
3288 argv is a list or tuple of strings and env is a dictionary
3289 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003290
Victor Stinnerd6f85422010-05-05 23:33:33 +00003291 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3292 Py_FileSystemDefaultEncoding,
3293 &path, &argv, &env))
3294 return NULL;
3295 if (PyList_Check(argv)) {
3296 argc = PyList_Size(argv);
3297 getitem = PyList_GetItem;
3298 }
3299 else if (PyTuple_Check(argv)) {
3300 argc = PyTuple_Size(argv);
3301 getitem = PyTuple_GetItem;
3302 }
3303 else {
3304 PyErr_SetString(PyExc_TypeError,
3305 "spawnve() arg 2 must be a tuple or list");
3306 goto fail_0;
3307 }
3308 if (!PyMapping_Check(env)) {
3309 PyErr_SetString(PyExc_TypeError,
3310 "spawnve() arg 3 must be a mapping object");
3311 goto fail_0;
3312 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003313
Victor Stinnerd6f85422010-05-05 23:33:33 +00003314 argvlist = PyMem_NEW(char *, argc+1);
3315 if (argvlist == NULL) {
3316 PyErr_NoMemory();
3317 goto fail_0;
3318 }
3319 for (i = 0; i < argc; i++) {
3320 if (!PyArg_Parse((*getitem)(argv, i),
3321 "et;spawnve() arg 2 must contain only strings",
3322 Py_FileSystemDefaultEncoding,
3323 &argvlist[i]))
3324 {
3325 lastarg = i;
3326 goto fail_1;
3327 }
3328 }
3329 lastarg = argc;
3330 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003331
Victor Stinnerd6f85422010-05-05 23:33:33 +00003332 i = PyMapping_Size(env);
3333 if (i < 0)
3334 goto fail_1;
3335 envlist = PyMem_NEW(char *, i + 1);
3336 if (envlist == NULL) {
3337 PyErr_NoMemory();
3338 goto fail_1;
3339 }
3340 envc = 0;
3341 keys = PyMapping_Keys(env);
3342 vals = PyMapping_Values(env);
3343 if (!keys || !vals)
3344 goto fail_2;
3345 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3346 PyErr_SetString(PyExc_TypeError,
3347 "spawnve(): env.keys() or env.values() is not a list");
3348 goto fail_2;
3349 }
Tim Peters5aa91602002-01-30 05:46:57 +00003350
Victor Stinnerd6f85422010-05-05 23:33:33 +00003351 for (pos = 0; pos < i; pos++) {
3352 char *p, *k, *v;
3353 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003354
Victor Stinnerd6f85422010-05-05 23:33:33 +00003355 key = PyList_GetItem(keys, pos);
3356 val = PyList_GetItem(vals, pos);
3357 if (!key || !val)
3358 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003359
Victor Stinnerd6f85422010-05-05 23:33:33 +00003360 if (!PyArg_Parse(
3361 key,
3362 "s;spawnve() arg 3 contains a non-string key",
3363 &k) ||
3364 !PyArg_Parse(
3365 val,
3366 "s;spawnve() arg 3 contains a non-string value",
3367 &v))
3368 {
3369 goto fail_2;
3370 }
3371 len = PyString_Size(key) + PyString_Size(val) + 2;
3372 p = PyMem_NEW(char, len);
3373 if (p == NULL) {
3374 PyErr_NoMemory();
3375 goto fail_2;
3376 }
3377 PyOS_snprintf(p, len, "%s=%s", k, v);
3378 envlist[envc++] = p;
3379 }
3380 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003381
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003382#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003383 Py_BEGIN_ALLOW_THREADS
3384 spawnval = spawnve(mode, path, argvlist, envlist);
3385 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003386#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003387 if (mode == _OLD_P_OVERLAY)
3388 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003389
Victor Stinnerd6f85422010-05-05 23:33:33 +00003390 Py_BEGIN_ALLOW_THREADS
3391 spawnval = _spawnve(mode, path, argvlist, envlist);
3392 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003393#endif
Tim Peters25059d32001-12-07 20:35:43 +00003394
Victor Stinnerd6f85422010-05-05 23:33:33 +00003395 if (spawnval == -1)
3396 (void) posix_error();
3397 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003398#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003399 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003400#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003401 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003402#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003403
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003404 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003405 while (--envc >= 0)
3406 PyMem_DEL(envlist[envc]);
3407 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003408 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003409 free_string_array(argvlist, lastarg);
3410 Py_XDECREF(vals);
3411 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003412 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003413 PyMem_Free(path);
3414 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003415}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003416
3417/* OS/2 supports spawnvp & spawnvpe natively */
3418#if defined(PYOS_OS2)
3419PyDoc_STRVAR(posix_spawnvp__doc__,
3420"spawnvp(mode, file, args)\n\n\
3421Execute the program 'file' in a new process, using the environment\n\
3422search path to find the file.\n\
3423\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003424 mode: mode of process creation\n\
3425 file: executable file name\n\
3426 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003427
3428static PyObject *
3429posix_spawnvp(PyObject *self, PyObject *args)
3430{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003431 char *path;
3432 PyObject *argv;
3433 char **argvlist;
3434 int mode, i, argc;
3435 Py_intptr_t spawnval;
3436 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003437
Victor Stinnerd6f85422010-05-05 23:33:33 +00003438 /* spawnvp has three arguments: (mode, path, argv), where
3439 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003440
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3442 Py_FileSystemDefaultEncoding,
3443 &path, &argv))
3444 return NULL;
3445 if (PyList_Check(argv)) {
3446 argc = PyList_Size(argv);
3447 getitem = PyList_GetItem;
3448 }
3449 else if (PyTuple_Check(argv)) {
3450 argc = PyTuple_Size(argv);
3451 getitem = PyTuple_GetItem;
3452 }
3453 else {
3454 PyErr_SetString(PyExc_TypeError,
3455 "spawnvp() arg 2 must be a tuple or list");
3456 PyMem_Free(path);
3457 return NULL;
3458 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003459
Victor Stinnerd6f85422010-05-05 23:33:33 +00003460 argvlist = PyMem_NEW(char *, argc+1);
3461 if (argvlist == NULL) {
3462 PyMem_Free(path);
3463 return PyErr_NoMemory();
3464 }
3465 for (i = 0; i < argc; i++) {
3466 if (!PyArg_Parse((*getitem)(argv, i), "et",
3467 Py_FileSystemDefaultEncoding,
3468 &argvlist[i])) {
3469 free_string_array(argvlist, i);
3470 PyErr_SetString(
3471 PyExc_TypeError,
3472 "spawnvp() arg 2 must contain only strings");
3473 PyMem_Free(path);
3474 return NULL;
3475 }
3476 }
3477 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003478
Victor Stinnerd6f85422010-05-05 23:33:33 +00003479 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003481 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003482#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003484#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003486
Victor Stinnerd6f85422010-05-05 23:33:33 +00003487 free_string_array(argvlist, argc);
3488 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003489
Victor Stinnerd6f85422010-05-05 23:33:33 +00003490 if (spawnval == -1)
3491 return posix_error();
3492 else
3493 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003494}
3495
3496
3497PyDoc_STRVAR(posix_spawnvpe__doc__,
3498"spawnvpe(mode, file, args, env)\n\n\
3499Execute the program 'file' in a new process, using the environment\n\
3500search path to find the file.\n\
3501\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003502 mode: mode of process creation\n\
3503 file: executable file name\n\
3504 args: tuple or list of arguments\n\
3505 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003506
3507static PyObject *
3508posix_spawnvpe(PyObject *self, PyObject *args)
3509{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003510 char *path;
3511 PyObject *argv, *env;
3512 char **argvlist;
3513 char **envlist;
3514 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3515 int mode, i, pos, argc, envc;
3516 Py_intptr_t spawnval;
3517 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3518 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003519
Victor Stinnerd6f85422010-05-05 23:33:33 +00003520 /* spawnvpe has four arguments: (mode, path, argv, env), where
3521 argv is a list or tuple of strings and env is a dictionary
3522 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003523
Victor Stinnerd6f85422010-05-05 23:33:33 +00003524 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3525 Py_FileSystemDefaultEncoding,
3526 &path, &argv, &env))
3527 return NULL;
3528 if (PyList_Check(argv)) {
3529 argc = PyList_Size(argv);
3530 getitem = PyList_GetItem;
3531 }
3532 else if (PyTuple_Check(argv)) {
3533 argc = PyTuple_Size(argv);
3534 getitem = PyTuple_GetItem;
3535 }
3536 else {
3537 PyErr_SetString(PyExc_TypeError,
3538 "spawnvpe() arg 2 must be a tuple or list");
3539 goto fail_0;
3540 }
3541 if (!PyMapping_Check(env)) {
3542 PyErr_SetString(PyExc_TypeError,
3543 "spawnvpe() arg 3 must be a mapping object");
3544 goto fail_0;
3545 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003546
Victor Stinnerd6f85422010-05-05 23:33:33 +00003547 argvlist = PyMem_NEW(char *, argc+1);
3548 if (argvlist == NULL) {
3549 PyErr_NoMemory();
3550 goto fail_0;
3551 }
3552 for (i = 0; i < argc; i++) {
3553 if (!PyArg_Parse((*getitem)(argv, i),
3554 "et;spawnvpe() arg 2 must contain only strings",
3555 Py_FileSystemDefaultEncoding,
3556 &argvlist[i]))
3557 {
3558 lastarg = i;
3559 goto fail_1;
3560 }
3561 }
3562 lastarg = argc;
3563 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003564
Victor Stinnerd6f85422010-05-05 23:33:33 +00003565 i = PyMapping_Size(env);
3566 if (i < 0)
3567 goto fail_1;
3568 envlist = PyMem_NEW(char *, i + 1);
3569 if (envlist == NULL) {
3570 PyErr_NoMemory();
3571 goto fail_1;
3572 }
3573 envc = 0;
3574 keys = PyMapping_Keys(env);
3575 vals = PyMapping_Values(env);
3576 if (!keys || !vals)
3577 goto fail_2;
3578 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3579 PyErr_SetString(PyExc_TypeError,
3580 "spawnvpe(): env.keys() or env.values() is not a list");
3581 goto fail_2;
3582 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003583
Victor Stinnerd6f85422010-05-05 23:33:33 +00003584 for (pos = 0; pos < i; pos++) {
3585 char *p, *k, *v;
3586 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003587
Victor Stinnerd6f85422010-05-05 23:33:33 +00003588 key = PyList_GetItem(keys, pos);
3589 val = PyList_GetItem(vals, pos);
3590 if (!key || !val)
3591 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003592
Victor Stinnerd6f85422010-05-05 23:33:33 +00003593 if (!PyArg_Parse(
3594 key,
3595 "s;spawnvpe() arg 3 contains a non-string key",
3596 &k) ||
3597 !PyArg_Parse(
3598 val,
3599 "s;spawnvpe() arg 3 contains a non-string value",
3600 &v))
3601 {
3602 goto fail_2;
3603 }
3604 len = PyString_Size(key) + PyString_Size(val) + 2;
3605 p = PyMem_NEW(char, len);
3606 if (p == NULL) {
3607 PyErr_NoMemory();
3608 goto fail_2;
3609 }
3610 PyOS_snprintf(p, len, "%s=%s", k, v);
3611 envlist[envc++] = p;
3612 }
3613 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003614
Victor Stinnerd6f85422010-05-05 23:33:33 +00003615 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003616#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003617 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003618#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003619 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003621 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 if (spawnval == -1)
3624 (void) posix_error();
3625 else
3626 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003627
3628 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003629 while (--envc >= 0)
3630 PyMem_DEL(envlist[envc]);
3631 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003632 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003633 free_string_array(argvlist, lastarg);
3634 Py_XDECREF(vals);
3635 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003636 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003637 PyMem_Free(path);
3638 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003639}
3640#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003641#endif /* HAVE_SPAWNV */
3642
3643
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003644#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003645PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003646"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003647Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3648\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003649Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003650
3651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003652posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003653{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003654 pid_t pid;
3655 int result = 0;
3656 _PyImport_AcquireLock();
3657 pid = fork1();
3658 if (pid == 0) {
3659 /* child: this clobbers and resets the import lock. */
3660 PyOS_AfterFork();
3661 } else {
3662 /* parent: release the import lock. */
3663 result = _PyImport_ReleaseLock();
3664 }
3665 if (pid == -1)
3666 return posix_error();
3667 if (result < 0) {
3668 /* Don't clobber the OSError if the fork failed. */
3669 PyErr_SetString(PyExc_RuntimeError,
3670 "not holding the import lock");
3671 return NULL;
3672 }
3673 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003674}
3675#endif
3676
3677
Guido van Rossumad0ee831995-03-01 10:34:45 +00003678#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003679PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003680"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003681Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003682Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683
Barry Warsaw53699e91996-12-10 23:23:01 +00003684static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003685posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003686{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003687 pid_t pid;
3688 int result = 0;
3689 _PyImport_AcquireLock();
3690 pid = fork();
3691 if (pid == 0) {
3692 /* child: this clobbers and resets the import lock. */
3693 PyOS_AfterFork();
3694 } else {
3695 /* parent: release the import lock. */
3696 result = _PyImport_ReleaseLock();
3697 }
3698 if (pid == -1)
3699 return posix_error();
3700 if (result < 0) {
3701 /* Don't clobber the OSError if the fork failed. */
3702 PyErr_SetString(PyExc_RuntimeError,
3703 "not holding the import lock");
3704 return NULL;
3705 }
3706 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003707}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003708#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003709
Neal Norwitzb59798b2003-03-21 01:43:31 +00003710/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003711/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3712#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003713#define DEV_PTY_FILE "/dev/ptc"
3714#define HAVE_DEV_PTMX
3715#else
3716#define DEV_PTY_FILE "/dev/ptmx"
3717#endif
3718
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003719#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003720#ifdef HAVE_PTY_H
3721#include <pty.h>
3722#else
3723#ifdef HAVE_LIBUTIL_H
3724#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003725#else
3726#ifdef HAVE_UTIL_H
3727#include <util.h>
3728#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003729#endif /* HAVE_LIBUTIL_H */
3730#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003731#ifdef HAVE_STROPTS_H
3732#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003733#endif
3734#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003735
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003736#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003737PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003738"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003740
3741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003742posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003743{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003744 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003745#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003746 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003747#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003748#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003749 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003750#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003751 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003752#endif
3753#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003754
Thomas Wouters70c21a12000-07-14 14:28:33 +00003755#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003756 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3757 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003758#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003759 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3760 if (slave_name == NULL)
3761 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003762
Victor Stinnerd6f85422010-05-05 23:33:33 +00003763 slave_fd = open(slave_name, O_RDWR);
3764 if (slave_fd < 0)
3765 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003766#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003767 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3768 if (master_fd < 0)
3769 return posix_error();
3770 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3771 /* change permission of slave */
3772 if (grantpt(master_fd) < 0) {
3773 PyOS_setsig(SIGCHLD, sig_saved);
3774 return posix_error();
3775 }
3776 /* unlock slave */
3777 if (unlockpt(master_fd) < 0) {
3778 PyOS_setsig(SIGCHLD, sig_saved);
3779 return posix_error();
3780 }
3781 PyOS_setsig(SIGCHLD, sig_saved);
3782 slave_name = ptsname(master_fd); /* get name of slave */
3783 if (slave_name == NULL)
3784 return posix_error();
3785 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3786 if (slave_fd < 0)
3787 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003788#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003789 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3790 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003791#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003792 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003793#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003794#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003795#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003796
Victor Stinnerd6f85422010-05-05 23:33:33 +00003797 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003798
Fred Drake8cef4cf2000-06-28 16:40:38 +00003799}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003800#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003801
3802#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003803PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003804"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003805Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3806Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003807To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003808
3809static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003810posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003811{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003812 int master_fd = -1, result = 0;
3813 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003814
Victor Stinnerd6f85422010-05-05 23:33:33 +00003815 _PyImport_AcquireLock();
3816 pid = forkpty(&master_fd, NULL, NULL, NULL);
3817 if (pid == 0) {
3818 /* child: this clobbers and resets the import lock. */
3819 PyOS_AfterFork();
3820 } else {
3821 /* parent: release the import lock. */
3822 result = _PyImport_ReleaseLock();
3823 }
3824 if (pid == -1)
3825 return posix_error();
3826 if (result < 0) {
3827 /* Don't clobber the OSError if the fork failed. */
3828 PyErr_SetString(PyExc_RuntimeError,
3829 "not holding the import lock");
3830 return NULL;
3831 }
3832 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003833}
3834#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835
Guido van Rossumad0ee831995-03-01 10:34:45 +00003836#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003837PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003838"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Barry Warsaw53699e91996-12-10 23:23:01 +00003841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003842posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003844 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003845}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003846#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003848
Guido van Rossumad0ee831995-03-01 10:34:45 +00003849#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003851"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003853
Barry Warsaw53699e91996-12-10 23:23:01 +00003854static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003855posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003856{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003857 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003858}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003859#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003861
Guido van Rossumad0ee831995-03-01 10:34:45 +00003862#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003863PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003864"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003866
Barry Warsaw53699e91996-12-10 23:23:01 +00003867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003868posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003870 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003871}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003872#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003876"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003878
Barry Warsaw53699e91996-12-10 23:23:01 +00003879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003880posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003881{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003882 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003883}
3884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Fred Drakec9680921999-12-13 16:37:25 +00003886#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003888"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003890
3891static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003892posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003893{
3894 PyObject *result = NULL;
3895
Fred Drakec9680921999-12-13 16:37:25 +00003896#ifdef NGROUPS_MAX
3897#define MAX_GROUPS NGROUPS_MAX
3898#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003899 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003900#define MAX_GROUPS 64
3901#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003902 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003903
Victor Stinner59729ff2011-07-05 11:28:19 +02003904 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003905 * This is a helper variable to store the intermediate result when
3906 * that happens.
3907 *
3908 * To keep the code readable the OSX behaviour is unconditional,
3909 * according to the POSIX spec this should be safe on all unix-y
3910 * systems.
3911 */
3912 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003913 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003914
Victor Stinnerd6f85422010-05-05 23:33:33 +00003915 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003916 if (n < 0) {
3917 if (errno == EINVAL) {
3918 n = getgroups(0, NULL);
3919 if (n == -1) {
3920 return posix_error();
3921 }
3922 if (n == 0) {
3923 /* Avoid malloc(0) */
3924 alt_grouplist = grouplist;
3925 } else {
3926 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
3927 if (alt_grouplist == NULL) {
3928 errno = EINVAL;
3929 return posix_error();
3930 }
3931 n = getgroups(n, alt_grouplist);
3932 if (n == -1) {
3933 PyMem_Free(alt_grouplist);
3934 return posix_error();
3935 }
3936 }
3937 } else {
3938 return posix_error();
3939 }
3940 }
3941 result = PyList_New(n);
3942 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00003943 int i;
3944 for (i = 0; i < n; ++i) {
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003945 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003946 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00003947 Py_DECREF(result);
3948 result = NULL;
3949 break;
Fred Drakec9680921999-12-13 16:37:25 +00003950 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003951 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003952 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003953 }
3954
3955 if (alt_grouplist != grouplist) {
3956 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003957 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003958
Fred Drakec9680921999-12-13 16:37:25 +00003959 return result;
3960}
3961#endif
3962
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003963#ifdef HAVE_INITGROUPS
3964PyDoc_STRVAR(posix_initgroups__doc__,
3965"initgroups(username, gid) -> None\n\n\
3966Call the system initgroups() to initialize the group access list with all of\n\
3967the groups of which the specified username is a member, plus the specified\n\
3968group id.");
3969
3970static PyObject *
3971posix_initgroups(PyObject *self, PyObject *args)
3972{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003973 char *username;
3974 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003975
Victor Stinnerd6f85422010-05-05 23:33:33 +00003976 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3977 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003978
Victor Stinnerd6f85422010-05-05 23:33:33 +00003979 if (initgroups(username, (gid_t) gid) == -1)
3980 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003981
Victor Stinnerd6f85422010-05-05 23:33:33 +00003982 Py_INCREF(Py_None);
3983 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003984}
3985#endif
3986
Martin v. Löwis606edc12002-06-13 21:09:11 +00003987#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003988PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003990Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003991
3992static PyObject *
3993posix_getpgid(PyObject *self, PyObject *args)
3994{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003995 pid_t pid, pgid;
3996 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3997 return NULL;
3998 pgid = getpgid(pid);
3999 if (pgid < 0)
4000 return posix_error();
4001 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004002}
4003#endif /* HAVE_GETPGID */
4004
4005
Guido van Rossumb6775db1994-08-01 11:34:53 +00004006#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004008"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004010
Barry Warsaw53699e91996-12-10 23:23:01 +00004011static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004012posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004013{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004014#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004015 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004016#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004017 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004018#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004019}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004020#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004022
Guido van Rossumb6775db1994-08-01 11:34:53 +00004023#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004024PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004025"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004026Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004027
Barry Warsaw53699e91996-12-10 23:23:01 +00004028static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004029posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004030{
Guido van Rossum64933891994-10-20 21:56:42 +00004031#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004032 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004033#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004034 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004035#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004036 return posix_error();
4037 Py_INCREF(Py_None);
4038 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004039}
4040
Guido van Rossumb6775db1994-08-01 11:34:53 +00004041#endif /* HAVE_SETPGRP */
4042
Guido van Rossumad0ee831995-03-01 10:34:45 +00004043#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004045"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004047
Barry Warsaw53699e91996-12-10 23:23:01 +00004048static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004049posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004050{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004051 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004052}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004053#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Fred Drake12c6e2d1999-12-14 21:25:03 +00004056#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004060
4061static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004062posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004063{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004064 PyObject *result = NULL;
4065 char *name;
4066 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004067
Victor Stinnerd6f85422010-05-05 23:33:33 +00004068 errno = 0;
4069 name = getlogin();
4070 if (name == NULL) {
4071 if (errno)
4072 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004073 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004074 PyErr_SetString(PyExc_OSError,
4075 "unable to determine login name");
4076 }
4077 else
4078 result = PyString_FromString(name);
4079 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004080
Fred Drake12c6e2d1999-12-14 21:25:03 +00004081 return result;
4082}
4083#endif
4084
Guido van Rossumad0ee831995-03-01 10:34:45 +00004085#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004087"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004091posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004092{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004093 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004094}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004095#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossumad0ee831995-03-01 10:34:45 +00004098#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004100"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004104posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004105{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004106 pid_t pid;
4107 int sig;
4108 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4109 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004110#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004111 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4112 APIRET rc;
4113 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004114 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004115
4116 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4117 APIRET rc;
4118 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004119 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004120
4121 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004122 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004123#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004124 if (kill(pid, sig) == -1)
4125 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004126#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004127 Py_INCREF(Py_None);
4128 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004129}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004130#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004131
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004132#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004134"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004136
4137static PyObject *
4138posix_killpg(PyObject *self, PyObject *args)
4139{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004140 int sig;
4141 pid_t pgid;
4142 /* XXX some man pages make the `pgid` parameter an int, others
4143 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4144 take the same type. Moreover, pid_t is always at least as wide as
4145 int (else compilation of this module fails), which is safe. */
4146 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4147 return NULL;
4148 if (killpg(pgid, sig) == -1)
4149 return posix_error();
4150 Py_INCREF(Py_None);
4151 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004152}
4153#endif
4154
Brian Curtine5aa8862010-04-02 23:26:06 +00004155#ifdef MS_WINDOWS
4156PyDoc_STRVAR(win32_kill__doc__,
4157"kill(pid, sig)\n\n\
4158Kill a process with a signal.");
4159
4160static PyObject *
4161win32_kill(PyObject *self, PyObject *args)
4162{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004163 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004164 DWORD pid, sig, err;
4165 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004166
Victor Stinnerd6f85422010-05-05 23:33:33 +00004167 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4168 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004169
Victor Stinnerd6f85422010-05-05 23:33:33 +00004170 /* Console processes which share a common console can be sent CTRL+C or
4171 CTRL+BREAK events, provided they handle said events. */
4172 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4173 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4174 err = GetLastError();
4175 return PyErr_SetFromWindowsErr(err);
4176 }
4177 else
4178 Py_RETURN_NONE;
4179 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004180
Victor Stinnerd6f85422010-05-05 23:33:33 +00004181 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4182 attempt to open and terminate the process. */
4183 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4184 if (handle == NULL) {
4185 err = GetLastError();
4186 return PyErr_SetFromWindowsErr(err);
4187 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004188
Victor Stinnerd6f85422010-05-05 23:33:33 +00004189 if (TerminateProcess(handle, sig) == 0) {
4190 err = GetLastError();
4191 result = PyErr_SetFromWindowsErr(err);
4192 } else {
4193 Py_INCREF(Py_None);
4194 result = Py_None;
4195 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004196
Victor Stinnerd6f85422010-05-05 23:33:33 +00004197 CloseHandle(handle);
4198 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004199}
Brian Curtincaea7e82011-06-08 19:29:53 -05004200
Brian Curtin5446f082011-06-09 10:00:42 -05004201PyDoc_STRVAR(posix__isdir__doc__,
4202"Return true if the pathname refers to an existing directory.");
4203
Brian Curtincaea7e82011-06-08 19:29:53 -05004204static PyObject *
4205posix__isdir(PyObject *self, PyObject *args)
4206{
4207 PyObject *opath;
4208 char *path;
4209 PyUnicodeObject *po;
4210 DWORD attributes;
4211
4212 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
4213 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
4214
4215 attributes = GetFileAttributesW(wpath);
4216 if (attributes == INVALID_FILE_ATTRIBUTES)
4217 Py_RETURN_FALSE;
4218 goto check;
4219 }
4220 /* Drop the argument parsing error as narrow strings
4221 are also valid. */
4222 PyErr_Clear();
4223
4224 if (!PyArg_ParseTuple(args, "et:_isdir",
4225 Py_FileSystemDefaultEncoding, &path))
4226 return NULL;
4227
4228 attributes = GetFileAttributesA(path);
4229 if (attributes == INVALID_FILE_ATTRIBUTES)
4230 Py_RETURN_FALSE;
4231
4232check:
4233 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4234 Py_RETURN_TRUE;
4235 else
4236 Py_RETURN_FALSE;
4237}
Brian Curtine5aa8862010-04-02 23:26:06 +00004238#endif /* MS_WINDOWS */
4239
Guido van Rossumc0125471996-06-28 18:55:32 +00004240#ifdef HAVE_PLOCK
4241
4242#ifdef HAVE_SYS_LOCK_H
4243#include <sys/lock.h>
4244#endif
4245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004246PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004247"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004248Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004249
Barry Warsaw53699e91996-12-10 23:23:01 +00004250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004251posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004252{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004253 int op;
4254 if (!PyArg_ParseTuple(args, "i:plock", &op))
4255 return NULL;
4256 if (plock(op) == -1)
4257 return posix_error();
4258 Py_INCREF(Py_None);
4259 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004260}
4261#endif
4262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004263
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004264#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004265PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004266"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004267Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004269#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004270#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004271static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004272async_system(const char *command)
4273{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004274 char errormsg[256], args[1024];
4275 RESULTCODES rcodes;
4276 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004277
Victor Stinnerd6f85422010-05-05 23:33:33 +00004278 char *shell = getenv("COMSPEC");
4279 if (!shell)
4280 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004281
Victor Stinnerd6f85422010-05-05 23:33:33 +00004282 /* avoid overflowing the argument buffer */
4283 if (strlen(shell) + 3 + strlen(command) >= 1024)
4284 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004285
Victor Stinnerd6f85422010-05-05 23:33:33 +00004286 args[0] = '\0';
4287 strcat(args, shell);
4288 strcat(args, "/c ");
4289 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004290
Victor Stinnerd6f85422010-05-05 23:33:33 +00004291 /* execute asynchronously, inheriting the environment */
4292 rc = DosExecPgm(errormsg,
4293 sizeof(errormsg),
4294 EXEC_ASYNC,
4295 args,
4296 NULL,
4297 &rcodes,
4298 shell);
4299 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004300}
4301
Guido van Rossumd48f2521997-12-05 22:19:34 +00004302static FILE *
4303popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004304{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004305 int oldfd, tgtfd;
4306 HFILE pipeh[2];
4307 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004308
Victor Stinnerd6f85422010-05-05 23:33:33 +00004309 /* mode determines which of stdin or stdout is reconnected to
4310 * the pipe to the child
4311 */
4312 if (strchr(mode, 'r') != NULL) {
4313 tgt_fd = 1; /* stdout */
4314 } else if (strchr(mode, 'w')) {
4315 tgt_fd = 0; /* stdin */
4316 } else {
4317 *err = ERROR_INVALID_ACCESS;
4318 return NULL;
4319 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004320
Victor Stinnerd6f85422010-05-05 23:33:33 +00004321 /* setup the pipe */
4322 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4323 *err = rc;
4324 return NULL;
4325 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004326
Victor Stinnerd6f85422010-05-05 23:33:33 +00004327 /* prevent other threads accessing stdio */
4328 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004329
Victor Stinnerd6f85422010-05-05 23:33:33 +00004330 /* reconnect stdio and execute child */
4331 oldfd = dup(tgtfd);
4332 close(tgtfd);
4333 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4334 DosClose(pipeh[tgtfd]);
4335 rc = async_system(command);
4336 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004337
Victor Stinnerd6f85422010-05-05 23:33:33 +00004338 /* restore stdio */
4339 dup2(oldfd, tgtfd);
4340 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004341
Victor Stinnerd6f85422010-05-05 23:33:33 +00004342 /* allow other threads access to stdio */
4343 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004344
Victor Stinnerd6f85422010-05-05 23:33:33 +00004345 /* if execution of child was successful return file stream */
4346 if (rc == NO_ERROR)
4347 return fdopen(pipeh[1 - tgtfd], mode);
4348 else {
4349 DosClose(pipeh[1 - tgtfd]);
4350 *err = rc;
4351 return NULL;
4352 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004353}
4354
4355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004356posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004357{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004358 char *name;
4359 char *mode = "r";
4360 int err, bufsize = -1;
4361 FILE *fp;
4362 PyObject *f;
4363 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4364 return NULL;
4365 Py_BEGIN_ALLOW_THREADS
4366 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4367 Py_END_ALLOW_THREADS
4368 if (fp == NULL)
4369 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004370
Victor Stinnerd6f85422010-05-05 23:33:33 +00004371 f = PyFile_FromFile(fp, name, mode, fclose);
4372 if (f != NULL)
4373 PyFile_SetBufSize(f, bufsize);
4374 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004375}
4376
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004377#elif defined(PYCC_GCC)
4378
4379/* standard posix version of popen() support */
4380static PyObject *
4381posix_popen(PyObject *self, PyObject *args)
4382{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004383 char *name;
4384 char *mode = "r";
4385 int bufsize = -1;
4386 FILE *fp;
4387 PyObject *f;
4388 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4389 return NULL;
4390 Py_BEGIN_ALLOW_THREADS
4391 fp = popen(name, mode);
4392 Py_END_ALLOW_THREADS
4393 if (fp == NULL)
4394 return posix_error();
4395 f = PyFile_FromFile(fp, name, mode, pclose);
4396 if (f != NULL)
4397 PyFile_SetBufSize(f, bufsize);
4398 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004399}
4400
4401/* fork() under OS/2 has lots'o'warts
4402 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4403 * most of this code is a ripoff of the win32 code, but using the
4404 * capabilities of EMX's C library routines
4405 */
4406
4407/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4408#define POPEN_1 1
4409#define POPEN_2 2
4410#define POPEN_3 3
4411#define POPEN_4 4
4412
4413static PyObject *_PyPopen(char *, int, int, int);
4414static int _PyPclose(FILE *file);
4415
4416/*
4417 * Internal dictionary mapping popen* file pointers to process handles,
4418 * for use when retrieving the process exit code. See _PyPclose() below
4419 * for more information on this dictionary's use.
4420 */
4421static PyObject *_PyPopenProcs = NULL;
4422
4423/* os2emx version of popen2()
4424 *
4425 * The result of this function is a pipe (file) connected to the
4426 * process's stdin, and a pipe connected to the process's stdout.
4427 */
4428
4429static PyObject *
4430os2emx_popen2(PyObject *self, PyObject *args)
4431{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004432 PyObject *f;
4433 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004434
Victor Stinnerd6f85422010-05-05 23:33:33 +00004435 char *cmdstring;
4436 char *mode = "t";
4437 int bufsize = -1;
4438 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4439 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004440
Victor Stinnerd6f85422010-05-05 23:33:33 +00004441 if (*mode == 't')
4442 tm = O_TEXT;
4443 else if (*mode != 'b') {
4444 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4445 return NULL;
4446 } else
4447 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004448
Victor Stinnerd6f85422010-05-05 23:33:33 +00004449 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004450
Victor Stinnerd6f85422010-05-05 23:33:33 +00004451 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004452}
4453
4454/*
4455 * Variation on os2emx.popen2
4456 *
4457 * The result of this function is 3 pipes - the process's stdin,
4458 * stdout and stderr
4459 */
4460
4461static PyObject *
4462os2emx_popen3(PyObject *self, PyObject *args)
4463{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004464 PyObject *f;
4465 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004466
Victor Stinnerd6f85422010-05-05 23:33:33 +00004467 char *cmdstring;
4468 char *mode = "t";
4469 int bufsize = -1;
4470 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4471 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004472
Victor Stinnerd6f85422010-05-05 23:33:33 +00004473 if (*mode == 't')
4474 tm = O_TEXT;
4475 else if (*mode != 'b') {
4476 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4477 return NULL;
4478 } else
4479 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004480
Victor Stinnerd6f85422010-05-05 23:33:33 +00004481 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004482
Victor Stinnerd6f85422010-05-05 23:33:33 +00004483 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004484}
4485
4486/*
4487 * Variation on os2emx.popen2
4488 *
Tim Peters11b23062003-04-23 02:39:17 +00004489 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004490 * and stdout+stderr combined as a single pipe.
4491 */
4492
4493static PyObject *
4494os2emx_popen4(PyObject *self, PyObject *args)
4495{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004496 PyObject *f;
4497 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004498
Victor Stinnerd6f85422010-05-05 23:33:33 +00004499 char *cmdstring;
4500 char *mode = "t";
4501 int bufsize = -1;
4502 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4503 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004504
Victor Stinnerd6f85422010-05-05 23:33:33 +00004505 if (*mode == 't')
4506 tm = O_TEXT;
4507 else if (*mode != 'b') {
4508 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4509 return NULL;
4510 } else
4511 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004512
Victor Stinnerd6f85422010-05-05 23:33:33 +00004513 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004514
Victor Stinnerd6f85422010-05-05 23:33:33 +00004515 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004516}
4517
4518/* a couple of structures for convenient handling of multiple
4519 * file handles and pipes
4520 */
4521struct file_ref
4522{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004523 int handle;
4524 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004525};
4526
4527struct pipe_ref
4528{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004529 int rd;
4530 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004531};
4532
4533/* The following code is derived from the win32 code */
4534
4535static PyObject *
4536_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4537{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004538 struct file_ref stdio[3];
4539 struct pipe_ref p_fd[3];
4540 FILE *p_s[3];
4541 int file_count, i, pipe_err;
4542 pid_t pipe_pid;
4543 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4544 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004545
Victor Stinnerd6f85422010-05-05 23:33:33 +00004546 /* file modes for subsequent fdopen's on pipe handles */
4547 if (mode == O_TEXT)
4548 {
4549 rd_mode = "rt";
4550 wr_mode = "wt";
4551 }
4552 else
4553 {
4554 rd_mode = "rb";
4555 wr_mode = "wb";
4556 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004557
Victor Stinnerd6f85422010-05-05 23:33:33 +00004558 /* prepare shell references */
4559 if ((shell = getenv("EMXSHELL")) == NULL)
4560 if ((shell = getenv("COMSPEC")) == NULL)
4561 {
4562 errno = ENOENT;
4563 return posix_error();
4564 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004565
Victor Stinnerd6f85422010-05-05 23:33:33 +00004566 sh_name = _getname(shell);
4567 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4568 opt = "/c";
4569 else
4570 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004571
Victor Stinnerd6f85422010-05-05 23:33:33 +00004572 /* save current stdio fds + their flags, and set not inheritable */
4573 i = pipe_err = 0;
4574 while (pipe_err >= 0 && i < 3)
4575 {
4576 pipe_err = stdio[i].handle = dup(i);
4577 stdio[i].flags = fcntl(i, F_GETFD, 0);
4578 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4579 i++;
4580 }
4581 if (pipe_err < 0)
4582 {
4583 /* didn't get them all saved - clean up and bail out */
4584 int saved_err = errno;
4585 while (i-- > 0)
4586 {
4587 close(stdio[i].handle);
4588 }
4589 errno = saved_err;
4590 return posix_error();
4591 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004592
Victor Stinnerd6f85422010-05-05 23:33:33 +00004593 /* create pipe ends */
4594 file_count = 2;
4595 if (n == POPEN_3)
4596 file_count = 3;
4597 i = pipe_err = 0;
4598 while ((pipe_err == 0) && (i < file_count))
4599 pipe_err = pipe((int *)&p_fd[i++]);
4600 if (pipe_err < 0)
4601 {
4602 /* didn't get them all made - clean up and bail out */
4603 while (i-- > 0)
4604 {
4605 close(p_fd[i].wr);
4606 close(p_fd[i].rd);
4607 }
4608 errno = EPIPE;
4609 return posix_error();
4610 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004611
Victor Stinnerd6f85422010-05-05 23:33:33 +00004612 /* change the actual standard IO streams over temporarily,
4613 * making the retained pipe ends non-inheritable
4614 */
4615 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004616
Victor Stinnerd6f85422010-05-05 23:33:33 +00004617 /* - stdin */
4618 if (dup2(p_fd[0].rd, 0) == 0)
4619 {
4620 close(p_fd[0].rd);
4621 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4622 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4623 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4624 {
4625 close(p_fd[0].wr);
4626 pipe_err = -1;
4627 }
4628 }
4629 else
4630 {
4631 pipe_err = -1;
4632 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004633
Victor Stinnerd6f85422010-05-05 23:33:33 +00004634 /* - stdout */
4635 if (pipe_err == 0)
4636 {
4637 if (dup2(p_fd[1].wr, 1) == 1)
4638 {
4639 close(p_fd[1].wr);
4640 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4641 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4642 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4643 {
4644 close(p_fd[1].rd);
4645 pipe_err = -1;
4646 }
4647 }
4648 else
4649 {
4650 pipe_err = -1;
4651 }
4652 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004653
Victor Stinnerd6f85422010-05-05 23:33:33 +00004654 /* - stderr, as required */
4655 if (pipe_err == 0)
4656 switch (n)
4657 {
4658 case POPEN_3:
4659 {
4660 if (dup2(p_fd[2].wr, 2) == 2)
4661 {
4662 close(p_fd[2].wr);
4663 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4664 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4665 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4666 {
4667 close(p_fd[2].rd);
4668 pipe_err = -1;
4669 }
4670 }
4671 else
4672 {
4673 pipe_err = -1;
4674 }
4675 break;
4676 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004677
Victor Stinnerd6f85422010-05-05 23:33:33 +00004678 case POPEN_4:
4679 {
4680 if (dup2(1, 2) != 2)
4681 {
4682 pipe_err = -1;
4683 }
4684 break;
4685 }
4686 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004687
Victor Stinnerd6f85422010-05-05 23:33:33 +00004688 /* spawn the child process */
4689 if (pipe_err == 0)
4690 {
4691 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4692 if (pipe_pid == -1)
4693 {
4694 pipe_err = -1;
4695 }
4696 else
4697 {
4698 /* save the PID into the FILE structure
4699 * NOTE: this implementation doesn't actually
4700 * take advantage of this, but do it for
4701 * completeness - AIM Apr01
4702 */
4703 for (i = 0; i < file_count; i++)
4704 p_s[i]->_pid = pipe_pid;
4705 }
4706 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004707
Victor Stinnerd6f85422010-05-05 23:33:33 +00004708 /* reset standard IO to normal */
4709 for (i = 0; i < 3; i++)
4710 {
4711 dup2(stdio[i].handle, i);
4712 fcntl(i, F_SETFD, stdio[i].flags);
4713 close(stdio[i].handle);
4714 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004715
Victor Stinnerd6f85422010-05-05 23:33:33 +00004716 /* if any remnant problems, clean up and bail out */
4717 if (pipe_err < 0)
4718 {
4719 for (i = 0; i < 3; i++)
4720 {
4721 close(p_fd[i].rd);
4722 close(p_fd[i].wr);
4723 }
4724 errno = EPIPE;
4725 return posix_error_with_filename(cmdstring);
4726 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004727
Victor Stinnerd6f85422010-05-05 23:33:33 +00004728 /* build tuple of file objects to return */
4729 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4730 PyFile_SetBufSize(p_f[0], bufsize);
4731 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4732 PyFile_SetBufSize(p_f[1], bufsize);
4733 if (n == POPEN_3)
4734 {
4735 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4736 PyFile_SetBufSize(p_f[0], bufsize);
4737 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4738 }
4739 else
4740 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004741
Victor Stinnerd6f85422010-05-05 23:33:33 +00004742 /*
4743 * Insert the files we've created into the process dictionary
4744 * all referencing the list with the process handle and the
4745 * initial number of files (see description below in _PyPclose).
4746 * Since if _PyPclose later tried to wait on a process when all
4747 * handles weren't closed, it could create a deadlock with the
4748 * child, we spend some energy here to try to ensure that we
4749 * either insert all file handles into the dictionary or none
4750 * at all. It's a little clumsy with the various popen modes
4751 * and variable number of files involved.
4752 */
4753 if (!_PyPopenProcs)
4754 {
4755 _PyPopenProcs = PyDict_New();
4756 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004757
Victor Stinnerd6f85422010-05-05 23:33:33 +00004758 if (_PyPopenProcs)
4759 {
4760 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4761 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004762
Victor Stinnerd6f85422010-05-05 23:33:33 +00004763 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4764 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004765
Victor Stinnerd6f85422010-05-05 23:33:33 +00004766 procObj = PyList_New(2);
4767 pidObj = PyLong_FromPid(pipe_pid);
4768 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004769
Victor Stinnerd6f85422010-05-05 23:33:33 +00004770 if (procObj && pidObj && intObj)
4771 {
4772 PyList_SetItem(procObj, 0, pidObj);
4773 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004774
Victor Stinnerd6f85422010-05-05 23:33:33 +00004775 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4776 if (fileObj[0])
4777 {
4778 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4779 fileObj[0],
4780 procObj);
4781 }
4782 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4783 if (fileObj[1])
4784 {
4785 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4786 fileObj[1],
4787 procObj);
4788 }
4789 if (file_count >= 3)
4790 {
4791 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4792 if (fileObj[2])
4793 {
4794 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4795 fileObj[2],
4796 procObj);
4797 }
4798 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004799
Victor Stinnerd6f85422010-05-05 23:33:33 +00004800 if (ins_rc[0] < 0 || !fileObj[0] ||
4801 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4802 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4803 {
4804 /* Something failed - remove any dictionary
4805 * entries that did make it.
4806 */
4807 if (!ins_rc[0] && fileObj[0])
4808 {
4809 PyDict_DelItem(_PyPopenProcs,
4810 fileObj[0]);
4811 }
4812 if (!ins_rc[1] && fileObj[1])
4813 {
4814 PyDict_DelItem(_PyPopenProcs,
4815 fileObj[1]);
4816 }
4817 if (!ins_rc[2] && fileObj[2])
4818 {
4819 PyDict_DelItem(_PyPopenProcs,
4820 fileObj[2]);
4821 }
4822 }
4823 }
Tim Peters11b23062003-04-23 02:39:17 +00004824
Victor Stinnerd6f85422010-05-05 23:33:33 +00004825 /*
4826 * Clean up our localized references for the dictionary keys
4827 * and value since PyDict_SetItem will Py_INCREF any copies
4828 * that got placed in the dictionary.
4829 */
4830 Py_XDECREF(procObj);
4831 Py_XDECREF(fileObj[0]);
4832 Py_XDECREF(fileObj[1]);
4833 Py_XDECREF(fileObj[2]);
4834 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004835
Victor Stinnerd6f85422010-05-05 23:33:33 +00004836 /* Child is launched. */
4837 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004838}
4839
4840/*
4841 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4842 * exit code for the child process and return as a result of the close.
4843 *
4844 * This function uses the _PyPopenProcs dictionary in order to map the
4845 * input file pointer to information about the process that was
4846 * originally created by the popen* call that created the file pointer.
4847 * The dictionary uses the file pointer as a key (with one entry
4848 * inserted for each file returned by the original popen* call) and a
4849 * single list object as the value for all files from a single call.
4850 * The list object contains the Win32 process handle at [0], and a file
4851 * count at [1], which is initialized to the total number of file
4852 * handles using that list.
4853 *
4854 * This function closes whichever handle it is passed, and decrements
4855 * the file count in the dictionary for the process handle pointed to
4856 * by this file. On the last close (when the file count reaches zero),
4857 * this function will wait for the child process and then return its
4858 * exit code as the result of the close() operation. This permits the
4859 * files to be closed in any order - it is always the close() of the
4860 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004861 *
4862 * NOTE: This function is currently called with the GIL released.
4863 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004864 */
4865
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004866static int _PyPclose(FILE *file)
4867{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004868 int result;
4869 int exit_code;
4870 pid_t pipe_pid;
4871 PyObject *procObj, *pidObj, *intObj, *fileObj;
4872 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004873#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004874 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004875#endif
4876
Victor Stinnerd6f85422010-05-05 23:33:33 +00004877 /* Close the file handle first, to ensure it can't block the
4878 * child from exiting if it's the last handle.
4879 */
4880 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004881
4882#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004883 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004884#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004885 if (_PyPopenProcs)
4886 {
4887 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4888 (procObj = PyDict_GetItem(_PyPopenProcs,
4889 fileObj)) != NULL &&
4890 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4891 (intObj = PyList_GetItem(procObj,1)) != NULL)
4892 {
4893 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4894 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004895
Victor Stinnerd6f85422010-05-05 23:33:33 +00004896 if (file_count > 1)
4897 {
4898 /* Still other files referencing process */
4899 file_count--;
4900 PyList_SetItem(procObj,1,
4901 PyInt_FromLong((long) file_count));
4902 }
4903 else
4904 {
4905 /* Last file for this process */
4906 if (result != EOF &&
4907 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4908 {
4909 /* extract exit status */
4910 if (WIFEXITED(exit_code))
4911 {
4912 result = WEXITSTATUS(exit_code);
4913 }
4914 else
4915 {
4916 errno = EPIPE;
4917 result = -1;
4918 }
4919 }
4920 else
4921 {
4922 /* Indicate failure - this will cause the file object
4923 * to raise an I/O error and translate the last
4924 * error code from errno. We do have a problem with
4925 * last errors that overlap the normal errno table,
4926 * but that's a consistent problem with the file object.
4927 */
4928 result = -1;
4929 }
4930 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004931
Victor Stinnerd6f85422010-05-05 23:33:33 +00004932 /* Remove this file pointer from dictionary */
4933 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004934
Victor Stinnerd6f85422010-05-05 23:33:33 +00004935 if (PyDict_Size(_PyPopenProcs) == 0)
4936 {
4937 Py_DECREF(_PyPopenProcs);
4938 _PyPopenProcs = NULL;
4939 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004940
Victor Stinnerd6f85422010-05-05 23:33:33 +00004941 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004942
Victor Stinnerd6f85422010-05-05 23:33:33 +00004943 Py_XDECREF(fileObj);
4944 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004945
4946#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004947 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004948#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004949 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004950}
4951
4952#endif /* PYCC_??? */
4953
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004954#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004955
4956/*
4957 * Portable 'popen' replacement for Win32.
4958 *
4959 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4960 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004961 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004962 */
4963
4964#include <malloc.h>
4965#include <io.h>
4966#include <fcntl.h>
4967
4968/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4969#define POPEN_1 1
4970#define POPEN_2 2
4971#define POPEN_3 3
4972#define POPEN_4 4
4973
4974static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004975static int _PyPclose(FILE *file);
4976
4977/*
4978 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004979 * for use when retrieving the process exit code. See _PyPclose() below
4980 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004981 */
4982static PyObject *_PyPopenProcs = NULL;
4983
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004984
4985/* popen that works from a GUI.
4986 *
4987 * The result of this function is a pipe (file) connected to the
4988 * processes stdin or stdout, depending on the requested mode.
4989 */
4990
4991static PyObject *
4992posix_popen(PyObject *self, PyObject *args)
4993{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004994 PyObject *f;
4995 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Victor Stinnerd6f85422010-05-05 23:33:33 +00004997 char *cmdstring;
4998 char *mode = "r";
4999 int bufsize = -1;
5000 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5001 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005002
Victor Stinnerd6f85422010-05-05 23:33:33 +00005003 if (*mode == 'r')
5004 tm = _O_RDONLY;
5005 else if (*mode != 'w') {
5006 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5007 return NULL;
5008 } else
5009 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005010
Victor Stinnerd6f85422010-05-05 23:33:33 +00005011 if (bufsize != -1) {
5012 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5013 return NULL;
5014 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005015
Victor Stinnerd6f85422010-05-05 23:33:33 +00005016 if (*(mode+1) == 't')
5017 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5018 else if (*(mode+1) == 'b')
5019 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5020 else
5021 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005022
Victor Stinnerd6f85422010-05-05 23:33:33 +00005023 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005024}
5025
5026/* Variation on win32pipe.popen
5027 *
5028 * The result of this function is a pipe (file) connected to the
5029 * process's stdin, and a pipe connected to the process's stdout.
5030 */
5031
5032static PyObject *
5033win32_popen2(PyObject *self, PyObject *args)
5034{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005035 PyObject *f;
5036 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005037
Victor Stinnerd6f85422010-05-05 23:33:33 +00005038 char *cmdstring;
5039 char *mode = "t";
5040 int bufsize = -1;
5041 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5042 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005043
Victor Stinnerd6f85422010-05-05 23:33:33 +00005044 if (*mode == 't')
5045 tm = _O_TEXT;
5046 else if (*mode != 'b') {
5047 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5048 return NULL;
5049 } else
5050 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005051
Victor Stinnerd6f85422010-05-05 23:33:33 +00005052 if (bufsize != -1) {
5053 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5054 return NULL;
5055 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005056
Victor Stinnerd6f85422010-05-05 23:33:33 +00005057 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005058
Victor Stinnerd6f85422010-05-05 23:33:33 +00005059 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005060}
5061
5062/*
5063 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005064 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005065 * The result of this function is 3 pipes - the process's stdin,
5066 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005067 */
5068
5069static PyObject *
5070win32_popen3(PyObject *self, PyObject *args)
5071{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005072 PyObject *f;
5073 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005074
Victor Stinnerd6f85422010-05-05 23:33:33 +00005075 char *cmdstring;
5076 char *mode = "t";
5077 int bufsize = -1;
5078 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5079 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005080
Victor Stinnerd6f85422010-05-05 23:33:33 +00005081 if (*mode == 't')
5082 tm = _O_TEXT;
5083 else if (*mode != 'b') {
5084 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5085 return NULL;
5086 } else
5087 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005088
Victor Stinnerd6f85422010-05-05 23:33:33 +00005089 if (bufsize != -1) {
5090 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5091 return NULL;
5092 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005093
Victor Stinnerd6f85422010-05-05 23:33:33 +00005094 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005095
Victor Stinnerd6f85422010-05-05 23:33:33 +00005096 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005097}
5098
5099/*
5100 * Variation on win32pipe.popen
5101 *
Tim Peters5aa91602002-01-30 05:46:57 +00005102 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005103 * and stdout+stderr combined as a single pipe.
5104 */
5105
5106static PyObject *
5107win32_popen4(PyObject *self, PyObject *args)
5108{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005109 PyObject *f;
5110 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005111
Victor Stinnerd6f85422010-05-05 23:33:33 +00005112 char *cmdstring;
5113 char *mode = "t";
5114 int bufsize = -1;
5115 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5116 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005117
Victor Stinnerd6f85422010-05-05 23:33:33 +00005118 if (*mode == 't')
5119 tm = _O_TEXT;
5120 else if (*mode != 'b') {
5121 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5122 return NULL;
5123 } else
5124 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005125
Victor Stinnerd6f85422010-05-05 23:33:33 +00005126 if (bufsize != -1) {
5127 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5128 return NULL;
5129 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005130
Victor Stinnerd6f85422010-05-05 23:33:33 +00005131 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005132
Victor Stinnerd6f85422010-05-05 23:33:33 +00005133 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005134}
5135
Mark Hammond08501372001-01-31 07:30:29 +00005136static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005137_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005138 HANDLE hStdin,
5139 HANDLE hStdout,
5140 HANDLE hStderr,
5141 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005142{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005143 PROCESS_INFORMATION piProcInfo;
5144 STARTUPINFO siStartInfo;
5145 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5146 char *s1,*s2, *s3 = " /c ";
5147 const char *szConsoleSpawn = "w9xpopen.exe";
5148 int i;
5149 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005150
Victor Stinnerd6f85422010-05-05 23:33:33 +00005151 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5152 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005153
Victor Stinnerd6f85422010-05-05 23:33:33 +00005154 s1 = (char *)alloca(i);
5155 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5156 /* x < i, so x fits into an integer */
5157 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005158
Victor Stinnerd6f85422010-05-05 23:33:33 +00005159 /* Explicitly check if we are using COMMAND.COM. If we are
5160 * then use the w9xpopen hack.
5161 */
5162 comshell = s1 + x;
5163 while (comshell >= s1 && *comshell != '\\')
5164 --comshell;
5165 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005166
Victor Stinnerd6f85422010-05-05 23:33:33 +00005167 if (GetVersion() < 0x80000000 &&
5168 _stricmp(comshell, "command.com") != 0) {
5169 /* NT/2000 and not using command.com. */
5170 x = i + strlen(s3) + strlen(cmdstring) + 1;
5171 s2 = (char *)alloca(x);
5172 ZeroMemory(s2, x);
5173 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5174 }
5175 else {
5176 /*
5177 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5178 * the workaround listed in KB: Q150956
5179 */
5180 char modulepath[_MAX_PATH];
5181 struct stat statinfo;
5182 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5183 for (x = i = 0; modulepath[i]; i++)
5184 if (modulepath[i] == SEP)
5185 x = i+1;
5186 modulepath[x] = '\0';
5187 /* Create the full-name to w9xpopen, so we can test it exists */
5188 strncat(modulepath,
5189 szConsoleSpawn,
5190 (sizeof(modulepath)/sizeof(modulepath[0]))
5191 -strlen(modulepath));
5192 if (stat(modulepath, &statinfo) != 0) {
5193 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5194 /* Eeek - file-not-found - possibly an embedding
5195 situation - see if we can locate it in sys.prefix
5196 */
5197 strncpy(modulepath,
5198 Py_GetExecPrefix(),
5199 mplen);
5200 modulepath[mplen-1] = '\0';
5201 if (modulepath[strlen(modulepath)-1] != '\\')
5202 strcat(modulepath, "\\");
5203 strncat(modulepath,
5204 szConsoleSpawn,
5205 mplen-strlen(modulepath));
5206 /* No where else to look - raise an easily identifiable
5207 error, rather than leaving Windows to report
5208 "file not found" - as the user is probably blissfully
5209 unaware this shim EXE is used, and it will confuse them.
5210 (well, it confused me for a while ;-)
5211 */
5212 if (stat(modulepath, &statinfo) != 0) {
5213 PyErr_Format(PyExc_RuntimeError,
5214 "Can not locate '%s' which is needed "
5215 "for popen to work with your shell "
5216 "or platform.",
5217 szConsoleSpawn);
5218 return FALSE;
5219 }
5220 }
5221 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5222 strlen(modulepath) +
5223 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005224
Victor Stinnerd6f85422010-05-05 23:33:33 +00005225 s2 = (char *)alloca(x);
5226 ZeroMemory(s2, x);
5227 /* To maintain correct argument passing semantics,
5228 we pass the command-line as it stands, and allow
5229 quoting to be applied. w9xpopen.exe will then
5230 use its argv vector, and re-quote the necessary
5231 args for the ultimate child process.
5232 */
5233 PyOS_snprintf(
5234 s2, x,
5235 "\"%s\" %s%s%s",
5236 modulepath,
5237 s1,
5238 s3,
5239 cmdstring);
5240 /* Not passing CREATE_NEW_CONSOLE has been known to
5241 cause random failures on win9x. Specifically a
5242 dialog:
5243 "Your program accessed mem currently in use at xxx"
5244 and a hopeful warning about the stability of your
5245 system.
5246 Cost is Ctrl+C won't kill children, but anyone
5247 who cares can have a go!
5248 */
5249 dwProcessFlags |= CREATE_NEW_CONSOLE;
5250 }
5251 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005252
Victor Stinnerd6f85422010-05-05 23:33:33 +00005253 /* Could be an else here to try cmd.exe / command.com in the path
5254 Now we'll just error out.. */
5255 else {
5256 PyErr_SetString(PyExc_RuntimeError,
5257 "Cannot locate a COMSPEC environment variable to "
5258 "use as the shell");
5259 return FALSE;
5260 }
Tim Peters5aa91602002-01-30 05:46:57 +00005261
Victor Stinnerd6f85422010-05-05 23:33:33 +00005262 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5263 siStartInfo.cb = sizeof(STARTUPINFO);
5264 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5265 siStartInfo.hStdInput = hStdin;
5266 siStartInfo.hStdOutput = hStdout;
5267 siStartInfo.hStdError = hStderr;
5268 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005269
Victor Stinnerd6f85422010-05-05 23:33:33 +00005270 if (CreateProcess(NULL,
5271 s2,
5272 NULL,
5273 NULL,
5274 TRUE,
5275 dwProcessFlags,
5276 NULL,
5277 NULL,
5278 &siStartInfo,
5279 &piProcInfo) ) {
5280 /* Close the handles now so anyone waiting is woken. */
5281 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005282
Victor Stinnerd6f85422010-05-05 23:33:33 +00005283 /* Return process handle */
5284 *hProcess = piProcInfo.hProcess;
5285 return TRUE;
5286 }
5287 win32_error("CreateProcess", s2);
5288 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005289}
5290
5291/* The following code is based off of KB: Q190351 */
5292
5293static PyObject *
5294_PyPopen(char *cmdstring, int mode, int n)
5295{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005296 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5297 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5298 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005299
Victor Stinnerd6f85422010-05-05 23:33:33 +00005300 SECURITY_ATTRIBUTES saAttr;
5301 BOOL fSuccess;
5302 int fd1, fd2, fd3;
5303 FILE *f1, *f2, *f3;
5304 long file_count;
5305 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005306
Victor Stinnerd6f85422010-05-05 23:33:33 +00005307 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5308 saAttr.bInheritHandle = TRUE;
5309 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005310
Victor Stinnerd6f85422010-05-05 23:33:33 +00005311 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5312 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005313
Victor Stinnerd6f85422010-05-05 23:33:33 +00005314 /* Create new output read handle and the input write handle. Set
5315 * the inheritance properties to FALSE. Otherwise, the child inherits
5316 * these handles; resulting in non-closeable handles to the pipes
5317 * being created. */
5318 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5319 GetCurrentProcess(), &hChildStdinWrDup, 0,
5320 FALSE,
5321 DUPLICATE_SAME_ACCESS);
5322 if (!fSuccess)
5323 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005324
Victor Stinnerd6f85422010-05-05 23:33:33 +00005325 /* Close the inheritable version of ChildStdin
5326 that we're using. */
5327 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005328
Victor Stinnerd6f85422010-05-05 23:33:33 +00005329 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5330 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005331
Victor Stinnerd6f85422010-05-05 23:33:33 +00005332 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5333 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5334 FALSE, DUPLICATE_SAME_ACCESS);
5335 if (!fSuccess)
5336 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005337
Victor Stinnerd6f85422010-05-05 23:33:33 +00005338 /* Close the inheritable version of ChildStdout
5339 that we're using. */
5340 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341
Victor Stinnerd6f85422010-05-05 23:33:33 +00005342 if (n != POPEN_4) {
5343 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5344 return win32_error("CreatePipe", NULL);
5345 fSuccess = DuplicateHandle(GetCurrentProcess(),
5346 hChildStderrRd,
5347 GetCurrentProcess(),
5348 &hChildStderrRdDup, 0,
5349 FALSE, DUPLICATE_SAME_ACCESS);
5350 if (!fSuccess)
5351 return win32_error("DuplicateHandle", NULL);
5352 /* Close the inheritable version of ChildStdErr that we're using. */
5353 CloseHandle(hChildStderrRd);
5354 }
Tim Peters5aa91602002-01-30 05:46:57 +00005355
Victor Stinnerd6f85422010-05-05 23:33:33 +00005356 switch (n) {
5357 case POPEN_1:
5358 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5359 case _O_WRONLY | _O_TEXT:
5360 /* Case for writing to child Stdin in text mode. */
5361 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5362 f1 = _fdopen(fd1, "w");
5363 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5364 PyFile_SetBufSize(f, 0);
5365 /* We don't care about these pipes anymore, so close them. */
5366 CloseHandle(hChildStdoutRdDup);
5367 CloseHandle(hChildStderrRdDup);
5368 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005369
Victor Stinnerd6f85422010-05-05 23:33:33 +00005370 case _O_RDONLY | _O_TEXT:
5371 /* Case for reading from child Stdout in text mode. */
5372 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5373 f1 = _fdopen(fd1, "r");
5374 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5375 PyFile_SetBufSize(f, 0);
5376 /* We don't care about these pipes anymore, so close them. */
5377 CloseHandle(hChildStdinWrDup);
5378 CloseHandle(hChildStderrRdDup);
5379 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005380
Victor Stinnerd6f85422010-05-05 23:33:33 +00005381 case _O_RDONLY | _O_BINARY:
5382 /* Case for readinig from child Stdout in binary mode. */
5383 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5384 f1 = _fdopen(fd1, "rb");
5385 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5386 PyFile_SetBufSize(f, 0);
5387 /* We don't care about these pipes anymore, so close them. */
5388 CloseHandle(hChildStdinWrDup);
5389 CloseHandle(hChildStderrRdDup);
5390 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005391
Victor Stinnerd6f85422010-05-05 23:33:33 +00005392 case _O_WRONLY | _O_BINARY:
5393 /* Case for writing to child Stdin in binary mode. */
5394 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5395 f1 = _fdopen(fd1, "wb");
5396 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5397 PyFile_SetBufSize(f, 0);
5398 /* We don't care about these pipes anymore, so close them. */
5399 CloseHandle(hChildStdoutRdDup);
5400 CloseHandle(hChildStderrRdDup);
5401 break;
5402 }
5403 file_count = 1;
5404 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005405
Victor Stinnerd6f85422010-05-05 23:33:33 +00005406 case POPEN_2:
5407 case POPEN_4:
5408 {
5409 char *m1, *m2;
5410 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005411
Victor Stinnerd6f85422010-05-05 23:33:33 +00005412 if (mode & _O_TEXT) {
5413 m1 = "r";
5414 m2 = "w";
5415 } else {
5416 m1 = "rb";
5417 m2 = "wb";
5418 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005419
Victor Stinnerd6f85422010-05-05 23:33:33 +00005420 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5421 f1 = _fdopen(fd1, m2);
5422 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5423 f2 = _fdopen(fd2, m1);
5424 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5425 PyFile_SetBufSize(p1, 0);
5426 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5427 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005428
Victor Stinnerd6f85422010-05-05 23:33:33 +00005429 if (n != 4)
5430 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005431
Victor Stinnerd6f85422010-05-05 23:33:33 +00005432 f = PyTuple_Pack(2,p1,p2);
5433 Py_XDECREF(p1);
5434 Py_XDECREF(p2);
5435 file_count = 2;
5436 break;
5437 }
Tim Peters5aa91602002-01-30 05:46:57 +00005438
Victor Stinnerd6f85422010-05-05 23:33:33 +00005439 case POPEN_3:
5440 {
5441 char *m1, *m2;
5442 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005443
Victor Stinnerd6f85422010-05-05 23:33:33 +00005444 if (mode & _O_TEXT) {
5445 m1 = "r";
5446 m2 = "w";
5447 } else {
5448 m1 = "rb";
5449 m2 = "wb";
5450 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005451
Victor Stinnerd6f85422010-05-05 23:33:33 +00005452 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5453 f1 = _fdopen(fd1, m2);
5454 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5455 f2 = _fdopen(fd2, m1);
5456 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5457 f3 = _fdopen(fd3, m1);
5458 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5459 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5460 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5461 PyFile_SetBufSize(p1, 0);
5462 PyFile_SetBufSize(p2, 0);
5463 PyFile_SetBufSize(p3, 0);
5464 f = PyTuple_Pack(3,p1,p2,p3);
5465 Py_XDECREF(p1);
5466 Py_XDECREF(p2);
5467 Py_XDECREF(p3);
5468 file_count = 3;
5469 break;
5470 }
5471 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005472
Victor Stinnerd6f85422010-05-05 23:33:33 +00005473 if (n == POPEN_4) {
5474 if (!_PyPopenCreateProcess(cmdstring,
5475 hChildStdinRd,
5476 hChildStdoutWr,
5477 hChildStdoutWr,
5478 &hProcess))
5479 return NULL;
5480 }
5481 else {
5482 if (!_PyPopenCreateProcess(cmdstring,
5483 hChildStdinRd,
5484 hChildStdoutWr,
5485 hChildStderrWr,
5486 &hProcess))
5487 return NULL;
5488 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005489
Victor Stinnerd6f85422010-05-05 23:33:33 +00005490 /*
5491 * Insert the files we've created into the process dictionary
5492 * all referencing the list with the process handle and the
5493 * initial number of files (see description below in _PyPclose).
5494 * Since if _PyPclose later tried to wait on a process when all
5495 * handles weren't closed, it could create a deadlock with the
5496 * child, we spend some energy here to try to ensure that we
5497 * either insert all file handles into the dictionary or none
5498 * at all. It's a little clumsy with the various popen modes
5499 * and variable number of files involved.
5500 */
5501 if (!_PyPopenProcs) {
5502 _PyPopenProcs = PyDict_New();
5503 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005504
Victor Stinnerd6f85422010-05-05 23:33:33 +00005505 if (_PyPopenProcs) {
5506 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5507 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005508
Victor Stinnerd6f85422010-05-05 23:33:33 +00005509 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5510 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005511
Victor Stinnerd6f85422010-05-05 23:33:33 +00005512 procObj = PyList_New(2);
5513 hProcessObj = PyLong_FromVoidPtr(hProcess);
5514 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005515
Victor Stinnerd6f85422010-05-05 23:33:33 +00005516 if (procObj && hProcessObj && intObj) {
5517 PyList_SetItem(procObj,0,hProcessObj);
5518 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005519
Victor Stinnerd6f85422010-05-05 23:33:33 +00005520 fileObj[0] = PyLong_FromVoidPtr(f1);
5521 if (fileObj[0]) {
5522 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5523 fileObj[0],
5524 procObj);
5525 }
5526 if (file_count >= 2) {
5527 fileObj[1] = PyLong_FromVoidPtr(f2);
5528 if (fileObj[1]) {
5529 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5530 fileObj[1],
5531 procObj);
5532 }
5533 }
5534 if (file_count >= 3) {
5535 fileObj[2] = PyLong_FromVoidPtr(f3);
5536 if (fileObj[2]) {
5537 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5538 fileObj[2],
5539 procObj);
5540 }
5541 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005542
Victor Stinnerd6f85422010-05-05 23:33:33 +00005543 if (ins_rc[0] < 0 || !fileObj[0] ||
5544 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5545 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5546 /* Something failed - remove any dictionary
5547 * entries that did make it.
5548 */
5549 if (!ins_rc[0] && fileObj[0]) {
5550 PyDict_DelItem(_PyPopenProcs,
5551 fileObj[0]);
5552 }
5553 if (!ins_rc[1] && fileObj[1]) {
5554 PyDict_DelItem(_PyPopenProcs,
5555 fileObj[1]);
5556 }
5557 if (!ins_rc[2] && fileObj[2]) {
5558 PyDict_DelItem(_PyPopenProcs,
5559 fileObj[2]);
5560 }
5561 }
5562 }
Tim Peters5aa91602002-01-30 05:46:57 +00005563
Victor Stinnerd6f85422010-05-05 23:33:33 +00005564 /*
5565 * Clean up our localized references for the dictionary keys
5566 * and value since PyDict_SetItem will Py_INCREF any copies
5567 * that got placed in the dictionary.
5568 */
5569 Py_XDECREF(procObj);
5570 Py_XDECREF(fileObj[0]);
5571 Py_XDECREF(fileObj[1]);
5572 Py_XDECREF(fileObj[2]);
5573 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005574
Victor Stinnerd6f85422010-05-05 23:33:33 +00005575 /* Child is launched. Close the parents copy of those pipe
5576 * handles that only the child should have open. You need to
5577 * make sure that no handles to the write end of the output pipe
5578 * are maintained in this process or else the pipe will not close
5579 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005580
Victor Stinnerd6f85422010-05-05 23:33:33 +00005581 if (!CloseHandle(hChildStdinRd))
5582 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005583
Victor Stinnerd6f85422010-05-05 23:33:33 +00005584 if (!CloseHandle(hChildStdoutWr))
5585 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005586
Victor Stinnerd6f85422010-05-05 23:33:33 +00005587 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5588 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005589
Victor Stinnerd6f85422010-05-05 23:33:33 +00005590 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005591}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005592
5593/*
5594 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5595 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005596 *
5597 * This function uses the _PyPopenProcs dictionary in order to map the
5598 * input file pointer to information about the process that was
5599 * originally created by the popen* call that created the file pointer.
5600 * The dictionary uses the file pointer as a key (with one entry
5601 * inserted for each file returned by the original popen* call) and a
5602 * single list object as the value for all files from a single call.
5603 * The list object contains the Win32 process handle at [0], and a file
5604 * count at [1], which is initialized to the total number of file
5605 * handles using that list.
5606 *
5607 * This function closes whichever handle it is passed, and decrements
5608 * the file count in the dictionary for the process handle pointed to
5609 * by this file. On the last close (when the file count reaches zero),
5610 * this function will wait for the child process and then return its
5611 * exit code as the result of the close() operation. This permits the
5612 * files to be closed in any order - it is always the close() of the
5613 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005614 *
5615 * NOTE: This function is currently called with the GIL released.
5616 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005617 */
Tim Peters736aa322000-09-01 06:51:24 +00005618
Fredrik Lundh56055a42000-07-23 19:47:12 +00005619static int _PyPclose(FILE *file)
5620{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005621 int result;
5622 DWORD exit_code;
5623 HANDLE hProcess;
5624 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5625 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005626#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005627 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005628#endif
5629
Victor Stinnerd6f85422010-05-05 23:33:33 +00005630 /* Close the file handle first, to ensure it can't block the
5631 * child from exiting if it's the last handle.
5632 */
5633 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005634#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005635 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005636#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005637 if (_PyPopenProcs) {
5638 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5639 (procObj = PyDict_GetItem(_PyPopenProcs,
5640 fileObj)) != NULL &&
5641 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5642 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005643
Victor Stinnerd6f85422010-05-05 23:33:33 +00005644 hProcess = PyLong_AsVoidPtr(hProcessObj);
5645 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005646
Victor Stinnerd6f85422010-05-05 23:33:33 +00005647 if (file_count > 1) {
5648 /* Still other files referencing process */
5649 file_count--;
5650 PyList_SetItem(procObj,1,
5651 PyInt_FromLong(file_count));
5652 } else {
5653 /* Last file for this process */
5654 if (result != EOF &&
5655 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5656 GetExitCodeProcess(hProcess, &exit_code)) {
5657 /* Possible truncation here in 16-bit environments, but
5658 * real exit codes are just the lower byte in any event.
5659 */
5660 result = exit_code;
5661 } else {
5662 /* Indicate failure - this will cause the file object
5663 * to raise an I/O error and translate the last Win32
5664 * error code from errno. We do have a problem with
5665 * last errors that overlap the normal errno table,
5666 * but that's a consistent problem with the file object.
5667 */
5668 if (result != EOF) {
5669 /* If the error wasn't from the fclose(), then
5670 * set errno for the file object error handling.
5671 */
5672 errno = GetLastError();
5673 }
5674 result = -1;
5675 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005676
Victor Stinnerd6f85422010-05-05 23:33:33 +00005677 /* Free up the native handle at this point */
5678 CloseHandle(hProcess);
5679 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005680
Victor Stinnerd6f85422010-05-05 23:33:33 +00005681 /* Remove this file pointer from dictionary */
5682 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005683
Victor Stinnerd6f85422010-05-05 23:33:33 +00005684 if (PyDict_Size(_PyPopenProcs) == 0) {
5685 Py_DECREF(_PyPopenProcs);
5686 _PyPopenProcs = NULL;
5687 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005688
Victor Stinnerd6f85422010-05-05 23:33:33 +00005689 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005690
Victor Stinnerd6f85422010-05-05 23:33:33 +00005691 Py_XDECREF(fileObj);
5692 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005693
Tim Peters736aa322000-09-01 06:51:24 +00005694#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005695 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005696#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005697 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005698}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005699
5700#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005702posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005703{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005704 char *name;
5705 char *mode = "r";
5706 int bufsize = -1;
5707 FILE *fp;
5708 PyObject *f;
5709 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5710 return NULL;
5711 /* Strip mode of binary or text modifiers */
5712 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5713 mode = "r";
5714 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5715 mode = "w";
5716 Py_BEGIN_ALLOW_THREADS
5717 fp = popen(name, mode);
5718 Py_END_ALLOW_THREADS
5719 if (fp == NULL)
5720 return posix_error();
5721 f = PyFile_FromFile(fp, name, mode, pclose);
5722 if (f != NULL)
5723 PyFile_SetBufSize(f, bufsize);
5724 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005725}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005726
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005727#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005728#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005729
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005730
Guido van Rossumb6775db1994-08-01 11:34:53 +00005731#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005733"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734Set the current process's user id.");
5735
Barry Warsaw53699e91996-12-10 23:23:01 +00005736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005737posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005738{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005739 long uid_arg;
5740 uid_t uid;
5741 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5742 return NULL;
5743 uid = uid_arg;
5744 if (uid != uid_arg) {
5745 PyErr_SetString(PyExc_OverflowError, "user id too big");
5746 return NULL;
5747 }
5748 if (setuid(uid) < 0)
5749 return posix_error();
5750 Py_INCREF(Py_None);
5751 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005752}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005753#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005755
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005756#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005757PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005758"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759Set the current process's effective user id.");
5760
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005761static PyObject *
5762posix_seteuid (PyObject *self, PyObject *args)
5763{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005764 long euid_arg;
5765 uid_t euid;
5766 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5767 return NULL;
5768 euid = euid_arg;
5769 if (euid != euid_arg) {
5770 PyErr_SetString(PyExc_OverflowError, "user id too big");
5771 return NULL;
5772 }
5773 if (seteuid(euid) < 0) {
5774 return posix_error();
5775 } else {
5776 Py_INCREF(Py_None);
5777 return Py_None;
5778 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005779}
5780#endif /* HAVE_SETEUID */
5781
5782#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005784"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005785Set the current process's effective group id.");
5786
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005787static PyObject *
5788posix_setegid (PyObject *self, PyObject *args)
5789{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005790 long egid_arg;
5791 gid_t egid;
5792 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5793 return NULL;
5794 egid = egid_arg;
5795 if (egid != egid_arg) {
5796 PyErr_SetString(PyExc_OverflowError, "group id too big");
5797 return NULL;
5798 }
5799 if (setegid(egid) < 0) {
5800 return posix_error();
5801 } else {
5802 Py_INCREF(Py_None);
5803 return Py_None;
5804 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005805}
5806#endif /* HAVE_SETEGID */
5807
5808#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005810"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005811Set the current process's real and effective user ids.");
5812
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005813static PyObject *
5814posix_setreuid (PyObject *self, PyObject *args)
5815{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005816 long ruid_arg, euid_arg;
5817 uid_t ruid, euid;
5818 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5819 return NULL;
5820 if (ruid_arg == -1)
5821 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5822 else
5823 ruid = ruid_arg; /* otherwise, assign from our long */
5824 if (euid_arg == -1)
5825 euid = (uid_t)-1;
5826 else
5827 euid = euid_arg;
5828 if ((euid_arg != -1 && euid != euid_arg) ||
5829 (ruid_arg != -1 && ruid != ruid_arg)) {
5830 PyErr_SetString(PyExc_OverflowError, "user id too big");
5831 return NULL;
5832 }
5833 if (setreuid(ruid, euid) < 0) {
5834 return posix_error();
5835 } else {
5836 Py_INCREF(Py_None);
5837 return Py_None;
5838 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005839}
5840#endif /* HAVE_SETREUID */
5841
5842#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005844"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005845Set the current process's real and effective group ids.");
5846
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005847static PyObject *
5848posix_setregid (PyObject *self, PyObject *args)
5849{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005850 long rgid_arg, egid_arg;
5851 gid_t rgid, egid;
5852 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5853 return NULL;
5854 if (rgid_arg == -1)
5855 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5856 else
5857 rgid = rgid_arg; /* otherwise, assign from our long */
5858 if (egid_arg == -1)
5859 egid = (gid_t)-1;
5860 else
5861 egid = egid_arg;
5862 if ((egid_arg != -1 && egid != egid_arg) ||
5863 (rgid_arg != -1 && rgid != rgid_arg)) {
5864 PyErr_SetString(PyExc_OverflowError, "group id too big");
5865 return NULL;
5866 }
5867 if (setregid(rgid, egid) < 0) {
5868 return posix_error();
5869 } else {
5870 Py_INCREF(Py_None);
5871 return Py_None;
5872 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005873}
5874#endif /* HAVE_SETREGID */
5875
Guido van Rossumb6775db1994-08-01 11:34:53 +00005876#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005877PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005878"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005879Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005880
Barry Warsaw53699e91996-12-10 23:23:01 +00005881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005882posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005883{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005884 long gid_arg;
5885 gid_t gid;
5886 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5887 return NULL;
5888 gid = gid_arg;
5889 if (gid != gid_arg) {
5890 PyErr_SetString(PyExc_OverflowError, "group id too big");
5891 return NULL;
5892 }
5893 if (setgid(gid) < 0)
5894 return posix_error();
5895 Py_INCREF(Py_None);
5896 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005897}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005898#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005899
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005900#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005901PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005902"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005903Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005904
5905static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005906posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005907{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005908 int i, len;
5909 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005910
Victor Stinnerd6f85422010-05-05 23:33:33 +00005911 if (!PySequence_Check(groups)) {
5912 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5913 return NULL;
5914 }
5915 len = PySequence_Size(groups);
5916 if (len > MAX_GROUPS) {
5917 PyErr_SetString(PyExc_ValueError, "too many groups");
5918 return NULL;
5919 }
5920 for(i = 0; i < len; i++) {
5921 PyObject *elem;
5922 elem = PySequence_GetItem(groups, i);
5923 if (!elem)
5924 return NULL;
5925 if (!PyInt_Check(elem)) {
5926 if (!PyLong_Check(elem)) {
5927 PyErr_SetString(PyExc_TypeError,
5928 "groups must be integers");
5929 Py_DECREF(elem);
5930 return NULL;
5931 } else {
5932 unsigned long x = PyLong_AsUnsignedLong(elem);
5933 if (PyErr_Occurred()) {
5934 PyErr_SetString(PyExc_TypeError,
5935 "group id too big");
5936 Py_DECREF(elem);
5937 return NULL;
5938 }
5939 grouplist[i] = x;
5940 /* read back to see if it fits in gid_t */
5941 if (grouplist[i] != x) {
5942 PyErr_SetString(PyExc_TypeError,
5943 "group id too big");
5944 Py_DECREF(elem);
5945 return NULL;
5946 }
5947 }
5948 } else {
5949 long x = PyInt_AsLong(elem);
5950 grouplist[i] = x;
5951 if (grouplist[i] != x) {
5952 PyErr_SetString(PyExc_TypeError,
5953 "group id too big");
5954 Py_DECREF(elem);
5955 return NULL;
5956 }
5957 }
5958 Py_DECREF(elem);
5959 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005960
Victor Stinnerd6f85422010-05-05 23:33:33 +00005961 if (setgroups(len, grouplist) < 0)
5962 return posix_error();
5963 Py_INCREF(Py_None);
5964 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005965}
5966#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005967
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005968#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005969static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005970wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005971{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005972 PyObject *result;
5973 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005974
Victor Stinnerd6f85422010-05-05 23:33:33 +00005975 if (pid == -1)
5976 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005977
Victor Stinnerd6f85422010-05-05 23:33:33 +00005978 if (struct_rusage == NULL) {
5979 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5980 if (m == NULL)
5981 return NULL;
5982 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5983 Py_DECREF(m);
5984 if (struct_rusage == NULL)
5985 return NULL;
5986 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005987
Victor Stinnerd6f85422010-05-05 23:33:33 +00005988 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5989 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5990 if (!result)
5991 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005992
5993#ifndef doubletime
5994#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5995#endif
5996
Victor Stinnerd6f85422010-05-05 23:33:33 +00005997 PyStructSequence_SET_ITEM(result, 0,
5998 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5999 PyStructSequence_SET_ITEM(result, 1,
6000 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006001#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006002 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6003 SET_INT(result, 2, ru->ru_maxrss);
6004 SET_INT(result, 3, ru->ru_ixrss);
6005 SET_INT(result, 4, ru->ru_idrss);
6006 SET_INT(result, 5, ru->ru_isrss);
6007 SET_INT(result, 6, ru->ru_minflt);
6008 SET_INT(result, 7, ru->ru_majflt);
6009 SET_INT(result, 8, ru->ru_nswap);
6010 SET_INT(result, 9, ru->ru_inblock);
6011 SET_INT(result, 10, ru->ru_oublock);
6012 SET_INT(result, 11, ru->ru_msgsnd);
6013 SET_INT(result, 12, ru->ru_msgrcv);
6014 SET_INT(result, 13, ru->ru_nsignals);
6015 SET_INT(result, 14, ru->ru_nvcsw);
6016 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006017#undef SET_INT
6018
Victor Stinnerd6f85422010-05-05 23:33:33 +00006019 if (PyErr_Occurred()) {
6020 Py_DECREF(result);
6021 return NULL;
6022 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006023
Victor Stinnerd6f85422010-05-05 23:33:33 +00006024 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006025}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006026#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006027
6028#ifdef HAVE_WAIT3
6029PyDoc_STRVAR(posix_wait3__doc__,
6030"wait3(options) -> (pid, status, rusage)\n\n\
6031Wait for completion of a child process.");
6032
6033static PyObject *
6034posix_wait3(PyObject *self, PyObject *args)
6035{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006036 pid_t pid;
6037 int options;
6038 struct rusage ru;
6039 WAIT_TYPE status;
6040 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006041
Victor Stinnerd6f85422010-05-05 23:33:33 +00006042 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6043 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006044
Victor Stinnerd6f85422010-05-05 23:33:33 +00006045 Py_BEGIN_ALLOW_THREADS
6046 pid = wait3(&status, options, &ru);
6047 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006048
Victor Stinnerd6f85422010-05-05 23:33:33 +00006049 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006050}
6051#endif /* HAVE_WAIT3 */
6052
6053#ifdef HAVE_WAIT4
6054PyDoc_STRVAR(posix_wait4__doc__,
6055"wait4(pid, options) -> (pid, status, rusage)\n\n\
6056Wait for completion of a given child process.");
6057
6058static PyObject *
6059posix_wait4(PyObject *self, PyObject *args)
6060{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006061 pid_t pid;
6062 int options;
6063 struct rusage ru;
6064 WAIT_TYPE status;
6065 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006066
Victor Stinnerd6f85422010-05-05 23:33:33 +00006067 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6068 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006069
Victor Stinnerd6f85422010-05-05 23:33:33 +00006070 Py_BEGIN_ALLOW_THREADS
6071 pid = wait4(pid, &status, options, &ru);
6072 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006073
Victor Stinnerd6f85422010-05-05 23:33:33 +00006074 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006075}
6076#endif /* HAVE_WAIT4 */
6077
Guido van Rossumb6775db1994-08-01 11:34:53 +00006078#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Barry Warsaw53699e91996-12-10 23:23:01 +00006083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006085{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006086 pid_t pid;
6087 int options;
6088 WAIT_TYPE status;
6089 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006090
Victor Stinnerd6f85422010-05-05 23:33:33 +00006091 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6092 return NULL;
6093 Py_BEGIN_ALLOW_THREADS
6094 pid = waitpid(pid, &status, options);
6095 Py_END_ALLOW_THREADS
6096 if (pid == -1)
6097 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006098
Victor Stinnerd6f85422010-05-05 23:33:33 +00006099 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006100}
6101
Tim Petersab034fa2002-02-01 11:27:43 +00006102#elif defined(HAVE_CWAIT)
6103
6104/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006107"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006108
6109static PyObject *
6110posix_waitpid(PyObject *self, PyObject *args)
6111{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006112 Py_intptr_t pid;
6113 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006114
Victor Stinnerd6f85422010-05-05 23:33:33 +00006115 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6116 return NULL;
6117 Py_BEGIN_ALLOW_THREADS
6118 pid = _cwait(&status, pid, options);
6119 Py_END_ALLOW_THREADS
6120 if (pid == -1)
6121 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006122
Victor Stinnerd6f85422010-05-05 23:33:33 +00006123 /* shift the status left a byte so this is more like the POSIX waitpid */
6124 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006125}
6126#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Guido van Rossumad0ee831995-03-01 10:34:45 +00006128#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006129PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006130"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006132
Barry Warsaw53699e91996-12-10 23:23:01 +00006133static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006134posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006135{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006136 pid_t pid;
6137 WAIT_TYPE status;
6138 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006139
Victor Stinnerd6f85422010-05-05 23:33:33 +00006140 Py_BEGIN_ALLOW_THREADS
6141 pid = wait(&status);
6142 Py_END_ALLOW_THREADS
6143 if (pid == -1)
6144 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006145
Victor Stinnerd6f85422010-05-05 23:33:33 +00006146 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006147}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006148#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006152"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006153Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006154
Barry Warsaw53699e91996-12-10 23:23:01 +00006155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006156posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006157{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006158#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006159 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006160#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006161#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006162 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006163#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006164 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006165#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006166#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006167}
6168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006169
Guido van Rossumb6775db1994-08-01 11:34:53 +00006170#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006172"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006174
Barry Warsaw53699e91996-12-10 23:23:01 +00006175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006176posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006177{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006178 PyObject* v;
6179 char buf[MAXPATHLEN];
6180 char *path;
6181 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006182#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006183 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006184#endif
6185
Victor Stinnerd6f85422010-05-05 23:33:33 +00006186 if (!PyArg_ParseTuple(args, "et:readlink",
6187 Py_FileSystemDefaultEncoding, &path))
6188 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006189#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006190 v = PySequence_GetItem(args, 0);
6191 if (v == NULL) {
6192 PyMem_Free(path);
6193 return NULL;
6194 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006195
Victor Stinnerd6f85422010-05-05 23:33:33 +00006196 if (PyUnicode_Check(v)) {
6197 arg_is_unicode = 1;
6198 }
6199 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006200#endif
6201
Victor Stinnerd6f85422010-05-05 23:33:33 +00006202 Py_BEGIN_ALLOW_THREADS
6203 n = readlink(path, buf, (int) sizeof buf);
6204 Py_END_ALLOW_THREADS
6205 if (n < 0)
6206 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006207
Victor Stinnerd6f85422010-05-05 23:33:33 +00006208 PyMem_Free(path);
6209 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006210#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006211 if (arg_is_unicode) {
6212 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006213
Victor Stinnerd6f85422010-05-05 23:33:33 +00006214 w = PyUnicode_FromEncodedObject(v,
6215 Py_FileSystemDefaultEncoding,
6216 "strict");
6217 if (w != NULL) {
6218 Py_DECREF(v);
6219 v = w;
6220 }
6221 else {
6222 /* fall back to the original byte string, as
6223 discussed in patch #683592 */
6224 PyErr_Clear();
6225 }
6226 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006227#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006228 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006229}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006230#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006231
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006232
Guido van Rossumb6775db1994-08-01 11:34:53 +00006233#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006234PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006235"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006236Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006237
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006238static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006239posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006240{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006241 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006242}
6243#endif /* HAVE_SYMLINK */
6244
6245
6246#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006247#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6248static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006249system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006250{
6251 ULONG value = 0;
6252
6253 Py_BEGIN_ALLOW_THREADS
6254 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6255 Py_END_ALLOW_THREADS
6256
6257 return value;
6258}
6259
6260static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006261posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006262{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006263 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006264 return Py_BuildValue("ddddd",
6265 (double)0 /* t.tms_utime / HZ */,
6266 (double)0 /* t.tms_stime / HZ */,
6267 (double)0 /* t.tms_cutime / HZ */,
6268 (double)0 /* t.tms_cstime / HZ */,
6269 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006270}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006271#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006272#define NEED_TICKS_PER_SECOND
6273static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006274static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006275posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006276{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006277 struct tms t;
6278 clock_t c;
6279 errno = 0;
6280 c = times(&t);
6281 if (c == (clock_t) -1)
6282 return posix_error();
6283 return Py_BuildValue("ddddd",
6284 (double)t.tms_utime / ticks_per_second,
6285 (double)t.tms_stime / ticks_per_second,
6286 (double)t.tms_cutime / ticks_per_second,
6287 (double)t.tms_cstime / ticks_per_second,
6288 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006289}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006290#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006291#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006292
6293
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006294#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006295#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006296static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006297posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006298{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006299 FILETIME create, exit, kernel, user;
6300 HANDLE hProc;
6301 hProc = GetCurrentProcess();
6302 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6303 /* The fields of a FILETIME structure are the hi and lo part
6304 of a 64-bit value expressed in 100 nanosecond units.
6305 1e7 is one second in such units; 1e-7 the inverse.
6306 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6307 */
6308 return Py_BuildValue(
6309 "ddddd",
6310 (double)(user.dwHighDateTime*429.4967296 +
6311 user.dwLowDateTime*1e-7),
6312 (double)(kernel.dwHighDateTime*429.4967296 +
6313 kernel.dwLowDateTime*1e-7),
6314 (double)0,
6315 (double)0,
6316 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006317}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006318#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006319
6320#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006321PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006322"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006323Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006324#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006326
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006327#ifdef HAVE_GETSID
6328PyDoc_STRVAR(posix_getsid__doc__,
6329"getsid(pid) -> sid\n\n\
6330Call the system call getsid().");
6331
6332static PyObject *
6333posix_getsid(PyObject *self, PyObject *args)
6334{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006335 pid_t pid;
6336 int sid;
6337 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6338 return NULL;
6339 sid = getsid(pid);
6340 if (sid < 0)
6341 return posix_error();
6342 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006343}
6344#endif /* HAVE_GETSID */
6345
6346
Guido van Rossumb6775db1994-08-01 11:34:53 +00006347#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006351
Barry Warsaw53699e91996-12-10 23:23:01 +00006352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006353posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006354{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006355 if (setsid() < 0)
6356 return posix_error();
6357 Py_INCREF(Py_None);
6358 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006359}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006361
Guido van Rossumb6775db1994-08-01 11:34:53 +00006362#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006364"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006366
Barry Warsaw53699e91996-12-10 23:23:01 +00006367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006368posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006369{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006370 pid_t pid;
6371 int pgrp;
6372 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6373 return NULL;
6374 if (setpgid(pid, pgrp) < 0)
6375 return posix_error();
6376 Py_INCREF(Py_None);
6377 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006378}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006379#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006380
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006381
Guido van Rossumb6775db1994-08-01 11:34:53 +00006382#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006383PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006384"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006385Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006386
Barry Warsaw53699e91996-12-10 23:23:01 +00006387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006388posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006389{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006390 int fd;
6391 pid_t pgid;
6392 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6393 return NULL;
6394 pgid = tcgetpgrp(fd);
6395 if (pgid < 0)
6396 return posix_error();
6397 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006398}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006399#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006401
Guido van Rossumb6775db1994-08-01 11:34:53 +00006402#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006403PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006404"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006405Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006406
Barry Warsaw53699e91996-12-10 23:23:01 +00006407static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006408posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006409{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006410 int fd;
6411 pid_t pgid;
6412 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6413 return NULL;
6414 if (tcsetpgrp(fd, pgid) < 0)
6415 return posix_error();
6416 Py_INCREF(Py_None);
6417 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006418}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006419#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006420
Guido van Rossum687dd131993-05-17 08:34:16 +00006421/* Functions acting on file descriptors */
6422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006423PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006424"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006426
Barry Warsaw53699e91996-12-10 23:23:01 +00006427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006428posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006429{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006430 char *file = NULL;
6431 int flag;
6432 int mode = 0777;
6433 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006434
6435#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006436 PyUnicodeObject *po;
6437 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6438 Py_BEGIN_ALLOW_THREADS
6439 /* PyUnicode_AS_UNICODE OK without thread
6440 lock as it is a simple dereference. */
6441 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6442 Py_END_ALLOW_THREADS
6443 if (fd < 0)
6444 return posix_error();
6445 return PyInt_FromLong((long)fd);
6446 }
6447 /* Drop the argument parsing error as narrow strings
6448 are also valid. */
6449 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006450#endif
6451
Victor Stinnerd6f85422010-05-05 23:33:33 +00006452 if (!PyArg_ParseTuple(args, "eti|i",
6453 Py_FileSystemDefaultEncoding, &file,
6454 &flag, &mode))
6455 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006456
Victor Stinnerd6f85422010-05-05 23:33:33 +00006457 Py_BEGIN_ALLOW_THREADS
6458 fd = open(file, flag, mode);
6459 Py_END_ALLOW_THREADS
6460 if (fd < 0)
6461 return posix_error_with_allocated_filename(file);
6462 PyMem_Free(file);
6463 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006464}
6465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006467PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006468"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006470
Barry Warsaw53699e91996-12-10 23:23:01 +00006471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006472posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006473{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006474 int fd, res;
6475 if (!PyArg_ParseTuple(args, "i:close", &fd))
6476 return NULL;
6477 if (!_PyVerify_fd(fd))
6478 return posix_error();
6479 Py_BEGIN_ALLOW_THREADS
6480 res = close(fd);
6481 Py_END_ALLOW_THREADS
6482 if (res < 0)
6483 return posix_error();
6484 Py_INCREF(Py_None);
6485 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006486}
6487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006488
Victor Stinnerd6f85422010-05-05 23:33:33 +00006489PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006490"closerange(fd_low, fd_high)\n\n\
6491Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6492
6493static PyObject *
6494posix_closerange(PyObject *self, PyObject *args)
6495{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006496 int fd_from, fd_to, i;
6497 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6498 return NULL;
6499 Py_BEGIN_ALLOW_THREADS
6500 for (i = fd_from; i < fd_to; i++)
6501 if (_PyVerify_fd(i))
6502 close(i);
6503 Py_END_ALLOW_THREADS
6504 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006505}
6506
6507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006508PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006509"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006510Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006511
Barry Warsaw53699e91996-12-10 23:23:01 +00006512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006513posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006514{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006515 int fd;
6516 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6517 return NULL;
6518 if (!_PyVerify_fd(fd))
6519 return posix_error();
6520 Py_BEGIN_ALLOW_THREADS
6521 fd = dup(fd);
6522 Py_END_ALLOW_THREADS
6523 if (fd < 0)
6524 return posix_error();
6525 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006526}
6527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006528
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006529PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006530"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006532
Barry Warsaw53699e91996-12-10 23:23:01 +00006533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006534posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006535{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006536 int fd, fd2, res;
6537 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6538 return NULL;
6539 if (!_PyVerify_fd_dup2(fd, fd2))
6540 return posix_error();
6541 Py_BEGIN_ALLOW_THREADS
6542 res = dup2(fd, fd2);
6543 Py_END_ALLOW_THREADS
6544 if (res < 0)
6545 return posix_error();
6546 Py_INCREF(Py_None);
6547 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006548}
6549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006550
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006551PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006552"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006554
Barry Warsaw53699e91996-12-10 23:23:01 +00006555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006556posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006557{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006558 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006559#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006560 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006561#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006562 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006563#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006564 PyObject *posobj;
6565 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6566 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006567#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006568 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6569 switch (how) {
6570 case 0: how = SEEK_SET; break;
6571 case 1: how = SEEK_CUR; break;
6572 case 2: how = SEEK_END; break;
6573 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006574#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006575
6576#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006577 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006578#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006579 pos = PyLong_Check(posobj) ?
6580 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006581#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006582 if (PyErr_Occurred())
6583 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006584
Victor Stinnerd6f85422010-05-05 23:33:33 +00006585 if (!_PyVerify_fd(fd))
6586 return posix_error();
6587 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006588#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006589 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006590#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006591 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006592#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006593 Py_END_ALLOW_THREADS
6594 if (res < 0)
6595 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006596
6597#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006598 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006599#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006600 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006601#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006602}
6603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006605PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006606"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006607Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006608
Barry Warsaw53699e91996-12-10 23:23:01 +00006609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006610posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006611{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006612 int fd, size, n;
6613 PyObject *buffer;
6614 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6615 return NULL;
6616 if (size < 0) {
6617 errno = EINVAL;
6618 return posix_error();
6619 }
6620 buffer = PyString_FromStringAndSize((char *)NULL, size);
6621 if (buffer == NULL)
6622 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006623 if (!_PyVerify_fd(fd)) {
6624 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006625 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006626 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006627 Py_BEGIN_ALLOW_THREADS
6628 n = read(fd, PyString_AsString(buffer), size);
6629 Py_END_ALLOW_THREADS
6630 if (n < 0) {
6631 Py_DECREF(buffer);
6632 return posix_error();
6633 }
6634 if (n != size)
6635 _PyString_Resize(&buffer, n);
6636 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006637}
6638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006639
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006640PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006641"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006642Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006643
Barry Warsaw53699e91996-12-10 23:23:01 +00006644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006645posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006646{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006647 Py_buffer pbuf;
6648 int fd;
Victor Stinner59729ff2011-07-05 11:28:19 +02006649 Py_ssize_t size, len;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006650
Victor Stinnerd6f85422010-05-05 23:33:33 +00006651 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6652 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006653 if (!_PyVerify_fd(fd)) {
6654 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006655 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006656 }
Victor Stinner59729ff2011-07-05 11:28:19 +02006657 len = pbuf.len;
Victor Stinnerd6f85422010-05-05 23:33:33 +00006658 Py_BEGIN_ALLOW_THREADS
Victor Stinner59729ff2011-07-05 11:28:19 +02006659#if defined(MS_WIN64) || defined(MS_WINDOWS)
6660 if (len > INT_MAX)
6661 len = INT_MAX;
6662 size = write(fd, pbuf.buf, (int)len);
6663#else
6664 size = write(fd, pbuf.buf, len);
6665#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006666 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006667 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006668 if (size < 0)
6669 return posix_error();
6670 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006671}
6672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006674PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006675"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006676Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006677
Barry Warsaw53699e91996-12-10 23:23:01 +00006678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006679posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006680{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006681 int fd;
6682 STRUCT_STAT st;
6683 int res;
6684 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6685 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006686#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006687 /* on OpenVMS we must ensure that all bytes are written to the file */
6688 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006689#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006690 if (!_PyVerify_fd(fd))
6691 return posix_error();
6692 Py_BEGIN_ALLOW_THREADS
6693 res = FSTAT(fd, &st);
6694 Py_END_ALLOW_THREADS
6695 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006696#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006697 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006698#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006699 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006700#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006701 }
Tim Peters5aa91602002-01-30 05:46:57 +00006702
Victor Stinnerd6f85422010-05-05 23:33:33 +00006703 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006704}
6705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006706
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006708"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006709Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006710
Barry Warsaw53699e91996-12-10 23:23:01 +00006711static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006712posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006713{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006714 int fd;
6715 char *orgmode = "r";
6716 int bufsize = -1;
6717 FILE *fp;
6718 PyObject *f;
6719 char *mode;
6720 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6721 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006722
Victor Stinnerd6f85422010-05-05 23:33:33 +00006723 /* Sanitize mode. See fileobject.c */
6724 mode = PyMem_MALLOC(strlen(orgmode)+3);
6725 if (!mode) {
6726 PyErr_NoMemory();
6727 return NULL;
6728 }
6729 strcpy(mode, orgmode);
6730 if (_PyFile_SanitizeMode(mode)) {
6731 PyMem_FREE(mode);
6732 return NULL;
6733 }
6734 if (!_PyVerify_fd(fd))
6735 return posix_error();
6736 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006737#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006738 if (mode[0] == 'a') {
6739 /* try to make sure the O_APPEND flag is set */
6740 int flags;
6741 flags = fcntl(fd, F_GETFL);
6742 if (flags != -1)
6743 fcntl(fd, F_SETFL, flags | O_APPEND);
6744 fp = fdopen(fd, mode);
6745 if (fp == NULL && flags != -1)
6746 /* restore old mode if fdopen failed */
6747 fcntl(fd, F_SETFL, flags);
6748 } else {
6749 fp = fdopen(fd, mode);
6750 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006751#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006752 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006753#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006754 Py_END_ALLOW_THREADS
6755 PyMem_FREE(mode);
6756 if (fp == NULL)
6757 return posix_error();
6758 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6759 if (f != NULL)
6760 PyFile_SetBufSize(f, bufsize);
6761 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006762}
6763
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006764PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006765"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006766Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006767connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006768
6769static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006770posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006771{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006772 int fd;
6773 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6774 return NULL;
6775 if (!_PyVerify_fd(fd))
6776 return PyBool_FromLong(0);
6777 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006778}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006779
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006780#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006781PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006782"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006783Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006784
Barry Warsaw53699e91996-12-10 23:23:01 +00006785static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006786posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006787{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006788#if defined(PYOS_OS2)
6789 HFILE read, write;
6790 APIRET rc;
6791
Victor Stinnerd6f85422010-05-05 23:33:33 +00006792 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006793 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006794 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006795 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006796 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006797
6798 return Py_BuildValue("(ii)", read, write);
6799#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006800#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006801 int fds[2];
6802 int res;
6803 Py_BEGIN_ALLOW_THREADS
6804 res = pipe(fds);
6805 Py_END_ALLOW_THREADS
6806 if (res != 0)
6807 return posix_error();
6808 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006809#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006810 HANDLE read, write;
6811 int read_fd, write_fd;
6812 BOOL ok;
6813 Py_BEGIN_ALLOW_THREADS
6814 ok = CreatePipe(&read, &write, NULL, 0);
6815 Py_END_ALLOW_THREADS
6816 if (!ok)
6817 return win32_error("CreatePipe", NULL);
6818 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6819 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6820 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006821#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006822#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006823}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006824#endif /* HAVE_PIPE */
6825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006826
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006827#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006828PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006829"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006830Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006831
Barry Warsaw53699e91996-12-10 23:23:01 +00006832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006833posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006834{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006835 char *filename;
6836 int mode = 0666;
6837 int res;
6838 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6839 return NULL;
6840 Py_BEGIN_ALLOW_THREADS
6841 res = mkfifo(filename, mode);
6842 Py_END_ALLOW_THREADS
6843 if (res < 0)
6844 return posix_error();
6845 Py_INCREF(Py_None);
6846 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006847}
6848#endif
6849
6850
Neal Norwitz11690112002-07-30 01:08:28 +00006851#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006852PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006853"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006854Create a filesystem node (file, device special file or named pipe)\n\
6855named filename. mode specifies both the permissions to use and the\n\
6856type of node to be created, being combined (bitwise OR) with one of\n\
6857S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006858device defines the newly created device special file (probably using\n\
6859os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006860
6861
6862static PyObject *
6863posix_mknod(PyObject *self, PyObject *args)
6864{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006865 char *filename;
6866 int mode = 0600;
6867 int device = 0;
6868 int res;
6869 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6870 return NULL;
6871 Py_BEGIN_ALLOW_THREADS
6872 res = mknod(filename, mode, device);
6873 Py_END_ALLOW_THREADS
6874 if (res < 0)
6875 return posix_error();
6876 Py_INCREF(Py_None);
6877 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006878}
6879#endif
6880
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006881#ifdef HAVE_DEVICE_MACROS
6882PyDoc_STRVAR(posix_major__doc__,
6883"major(device) -> major number\n\
6884Extracts a device major number from a raw device number.");
6885
6886static PyObject *
6887posix_major(PyObject *self, PyObject *args)
6888{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006889 int device;
6890 if (!PyArg_ParseTuple(args, "i:major", &device))
6891 return NULL;
6892 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006893}
6894
6895PyDoc_STRVAR(posix_minor__doc__,
6896"minor(device) -> minor number\n\
6897Extracts a device minor number from a raw device number.");
6898
6899static PyObject *
6900posix_minor(PyObject *self, PyObject *args)
6901{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006902 int device;
6903 if (!PyArg_ParseTuple(args, "i:minor", &device))
6904 return NULL;
6905 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006906}
6907
6908PyDoc_STRVAR(posix_makedev__doc__,
6909"makedev(major, minor) -> device number\n\
6910Composes a raw device number from the major and minor device numbers.");
6911
6912static PyObject *
6913posix_makedev(PyObject *self, PyObject *args)
6914{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006915 int major, minor;
6916 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6917 return NULL;
6918 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006919}
6920#endif /* device macros */
6921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006922
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006923#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006924PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006925"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006926Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006927
Barry Warsaw53699e91996-12-10 23:23:01 +00006928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006929posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006930{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006931 int fd;
6932 off_t length;
6933 int res;
6934 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006935
Victor Stinnerd6f85422010-05-05 23:33:33 +00006936 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6937 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006938
6939#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006940 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006941#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006942 length = PyLong_Check(lenobj) ?
6943 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006944#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006945 if (PyErr_Occurred())
6946 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006947
Victor Stinnerd6f85422010-05-05 23:33:33 +00006948 Py_BEGIN_ALLOW_THREADS
6949 res = ftruncate(fd, length);
6950 Py_END_ALLOW_THREADS
6951 if (res < 0)
6952 return posix_error();
6953 Py_INCREF(Py_None);
6954 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006955}
6956#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006957
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006958#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006959PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006960"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006961Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006962
Fred Drake762e2061999-08-26 17:23:54 +00006963/* Save putenv() parameters as values here, so we can collect them when they
6964 * get re-set with another call for the same key. */
6965static PyObject *posix_putenv_garbage;
6966
Tim Peters5aa91602002-01-30 05:46:57 +00006967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006968posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006969{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006970 char *s1, *s2;
6971 char *newenv;
6972 PyObject *newstr;
6973 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006974
Victor Stinnerd6f85422010-05-05 23:33:33 +00006975 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6976 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006977
6978#if defined(PYOS_OS2)
6979 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6980 APIRET rc;
6981
Guido van Rossumd48f2521997-12-05 22:19:34 +00006982 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6983 if (rc != NO_ERROR)
6984 return os2_error(rc);
6985
6986 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6987 APIRET rc;
6988
Guido van Rossumd48f2521997-12-05 22:19:34 +00006989 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6990 if (rc != NO_ERROR)
6991 return os2_error(rc);
6992 } else {
6993#endif
6994
Victor Stinnerd6f85422010-05-05 23:33:33 +00006995 /* XXX This can leak memory -- not easy to fix :-( */
6996 len = strlen(s1) + strlen(s2) + 2;
6997 /* len includes space for a trailing \0; the size arg to
6998 PyString_FromStringAndSize does not count that */
6999 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
7000 if (newstr == NULL)
7001 return PyErr_NoMemory();
7002 newenv = PyString_AS_STRING(newstr);
7003 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
7004 if (putenv(newenv)) {
7005 Py_DECREF(newstr);
7006 posix_error();
7007 return NULL;
7008 }
7009 /* Install the first arg and newstr in posix_putenv_garbage;
7010 * this will cause previous value to be collected. This has to
7011 * happen after the real putenv() call because the old value
7012 * was still accessible until then. */
7013 if (PyDict_SetItem(posix_putenv_garbage,
7014 PyTuple_GET_ITEM(args, 0), newstr)) {
7015 /* really not much we can do; just leak */
7016 PyErr_Clear();
7017 }
7018 else {
7019 Py_DECREF(newstr);
7020 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007021
7022#if defined(PYOS_OS2)
7023 }
7024#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007025 Py_INCREF(Py_None);
7026 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007027}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007028#endif /* putenv */
7029
Guido van Rossumc524d952001-10-19 01:31:59 +00007030#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007031PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007032"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007033Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007034
7035static PyObject *
7036posix_unsetenv(PyObject *self, PyObject *args)
7037{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007038 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007039
Victor Stinnerd6f85422010-05-05 23:33:33 +00007040 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7041 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007042
Victor Stinnerd6f85422010-05-05 23:33:33 +00007043 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007044
Victor Stinnerd6f85422010-05-05 23:33:33 +00007045 /* Remove the key from posix_putenv_garbage;
7046 * this will cause it to be collected. This has to
7047 * happen after the real unsetenv() call because the
7048 * old value was still accessible until then.
7049 */
7050 if (PyDict_DelItem(posix_putenv_garbage,
7051 PyTuple_GET_ITEM(args, 0))) {
7052 /* really not much we can do; just leak */
7053 PyErr_Clear();
7054 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007055
Victor Stinnerd6f85422010-05-05 23:33:33 +00007056 Py_INCREF(Py_None);
7057 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007058}
7059#endif /* unsetenv */
7060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007061PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007062"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007063Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007064
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007066posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007067{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007068 int code;
7069 char *message;
7070 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7071 return NULL;
7072 message = strerror(code);
7073 if (message == NULL) {
7074 PyErr_SetString(PyExc_ValueError,
7075 "strerror() argument out of range");
7076 return NULL;
7077 }
7078 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007079}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007080
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007081
Guido van Rossumc9641791998-08-04 15:26:23 +00007082#ifdef HAVE_SYS_WAIT_H
7083
Fred Drake106c1a02002-04-23 15:58:02 +00007084#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007085PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007086"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007087Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007088
7089static PyObject *
7090posix_WCOREDUMP(PyObject *self, PyObject *args)
7091{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007092 WAIT_TYPE status;
7093 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007094
Victor Stinnerd6f85422010-05-05 23:33:33 +00007095 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7096 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007097
Victor Stinnerd6f85422010-05-05 23:33:33 +00007098 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007099}
7100#endif /* WCOREDUMP */
7101
7102#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007103PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007104"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007105Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007106job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007107
7108static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007109posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007111 WAIT_TYPE status;
7112 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007113
Victor Stinnerd6f85422010-05-05 23:33:33 +00007114 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7115 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007116
Victor Stinnerd6f85422010-05-05 23:33:33 +00007117 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007118}
7119#endif /* WIFCONTINUED */
7120
Guido van Rossumc9641791998-08-04 15:26:23 +00007121#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007122PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007123"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007124Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007125
7126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007127posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007128{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007129 WAIT_TYPE status;
7130 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007131
Victor Stinnerd6f85422010-05-05 23:33:33 +00007132 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7133 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007134
Victor Stinnerd6f85422010-05-05 23:33:33 +00007135 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007136}
7137#endif /* WIFSTOPPED */
7138
7139#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007140PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007141"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007142Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007143
7144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007145posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007146{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007147 WAIT_TYPE status;
7148 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007149
Victor Stinnerd6f85422010-05-05 23:33:33 +00007150 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7151 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007152
Victor Stinnerd6f85422010-05-05 23:33:33 +00007153 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007154}
7155#endif /* WIFSIGNALED */
7156
7157#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007158PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007159"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007160Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007161system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007162
7163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007164posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007165{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007166 WAIT_TYPE status;
7167 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007168
Victor Stinnerd6f85422010-05-05 23:33:33 +00007169 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7170 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007171
Victor Stinnerd6f85422010-05-05 23:33:33 +00007172 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007173}
7174#endif /* WIFEXITED */
7175
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007176#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007177PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007178"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007179Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007180
7181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007182posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007183{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007184 WAIT_TYPE status;
7185 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007186
Victor Stinnerd6f85422010-05-05 23:33:33 +00007187 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7188 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007189
Victor Stinnerd6f85422010-05-05 23:33:33 +00007190 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007191}
7192#endif /* WEXITSTATUS */
7193
7194#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007195PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007196"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007197Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007198value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007199
7200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007201posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007202{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007203 WAIT_TYPE status;
7204 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007205
Victor Stinnerd6f85422010-05-05 23:33:33 +00007206 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7207 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007208
Victor Stinnerd6f85422010-05-05 23:33:33 +00007209 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007210}
7211#endif /* WTERMSIG */
7212
7213#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007214PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007215"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007216Return the signal that stopped the process that provided\n\
7217the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007218
7219static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007220posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007221{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007222 WAIT_TYPE status;
7223 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007224
Victor Stinnerd6f85422010-05-05 23:33:33 +00007225 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7226 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007227
Victor Stinnerd6f85422010-05-05 23:33:33 +00007228 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007229}
7230#endif /* WSTOPSIG */
7231
7232#endif /* HAVE_SYS_WAIT_H */
7233
7234
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007235#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007236#ifdef _SCO_DS
7237/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7238 needed definitions in sys/statvfs.h */
7239#define _SVID3
7240#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007241#include <sys/statvfs.h>
7242
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007243static PyObject*
7244_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007245 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7246 if (v == NULL)
7247 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007248
7249#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007250 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7251 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7252 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7253 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7254 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7255 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7256 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7257 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7258 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7259 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007260#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007261 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7262 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7263 PyStructSequence_SET_ITEM(v, 2,
7264 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7265 PyStructSequence_SET_ITEM(v, 3,
7266 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7267 PyStructSequence_SET_ITEM(v, 4,
7268 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7269 PyStructSequence_SET_ITEM(v, 5,
7270 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7271 PyStructSequence_SET_ITEM(v, 6,
7272 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7273 PyStructSequence_SET_ITEM(v, 7,
7274 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7275 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7276 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007277#endif
7278
Victor Stinnerd6f85422010-05-05 23:33:33 +00007279 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007280}
7281
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007282PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007283"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007284Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007285
7286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007287posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007289 int fd, res;
7290 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007291
Victor Stinnerd6f85422010-05-05 23:33:33 +00007292 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7293 return NULL;
7294 Py_BEGIN_ALLOW_THREADS
7295 res = fstatvfs(fd, &st);
7296 Py_END_ALLOW_THREADS
7297 if (res != 0)
7298 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007299
Victor Stinnerd6f85422010-05-05 23:33:33 +00007300 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007301}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007302#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007303
7304
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007305#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007306#include <sys/statvfs.h>
7307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007308PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007309"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007310Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007311
7312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007313posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007314{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007315 char *path;
7316 int res;
7317 struct statvfs st;
7318 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7319 return NULL;
7320 Py_BEGIN_ALLOW_THREADS
7321 res = statvfs(path, &st);
7322 Py_END_ALLOW_THREADS
7323 if (res != 0)
7324 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007325
Victor Stinnerd6f85422010-05-05 23:33:33 +00007326 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007327}
7328#endif /* HAVE_STATVFS */
7329
7330
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007332PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007333"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007334Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007335The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007336or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007337
7338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007339posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007340{
7341 PyObject *result = NULL;
7342 char *dir = NULL;
7343 char *pfx = NULL;
7344 char *name;
7345
7346 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007347 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007348
7349 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007350 "tempnam is a potential security risk to your program") < 0)
7351 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007352
Antoine Pitroub0614612011-01-02 20:04:52 +00007353 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7354 "use the tempfile module", 1) < 0)
7355 return NULL;
7356
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007357#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007358 name = _tempnam(dir, pfx);
7359#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007360 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007361#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007362 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007363 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007364 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 free(name);
7366 return result;
7367}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007368#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007369
7370
7371#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007372PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007373"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007375
7376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007377posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007378{
7379 FILE *fp;
7380
Antoine Pitroub0614612011-01-02 20:04:52 +00007381 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7382 "use the tempfile module", 1) < 0)
7383 return NULL;
7384
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007385 fp = tmpfile();
7386 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007387 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007388 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389}
7390#endif
7391
7392
7393#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007394PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007395"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007396Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007397
7398static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007399posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007400{
7401 char buffer[L_tmpnam];
7402 char *name;
7403
Skip Montanaro95618b52001-08-18 18:52:10 +00007404 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007405 "tmpnam is a potential security risk to your program") < 0)
7406 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007407
Antoine Pitroub0614612011-01-02 20:04:52 +00007408 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7409 "use the tempfile module", 1) < 0)
7410 return NULL;
7411
Greg Wardb48bc172000-03-01 21:51:56 +00007412#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007413 name = tmpnam_r(buffer);
7414#else
7415 name = tmpnam(buffer);
7416#endif
7417 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007418 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007419#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007420 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007421#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007422 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007424 );
7425 PyErr_SetObject(PyExc_OSError, err);
7426 Py_XDECREF(err);
7427 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007428 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007429 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007430}
7431#endif
7432
7433
Fred Drakec9680921999-12-13 16:37:25 +00007434/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7435 * It maps strings representing configuration variable names to
7436 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007437 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007438 * rarely-used constants. There are three separate tables that use
7439 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007440 *
7441 * This code is always included, even if none of the interfaces that
7442 * need it are included. The #if hackery needed to avoid it would be
7443 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007444 */
7445struct constdef {
7446 char *name;
7447 long value;
7448};
7449
Fred Drake12c6e2d1999-12-14 21:25:03 +00007450static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007451conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007452 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007453{
7454 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007455 *valuep = PyInt_AS_LONG(arg);
7456 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007457 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007458 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007459 /* look up the value in the table using a binary search */
7460 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007461 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007462 size_t hi = tablesize;
7463 int cmp;
7464 char *confname = PyString_AS_STRING(arg);
7465 while (lo < hi) {
7466 mid = (lo + hi) / 2;
7467 cmp = strcmp(confname, table[mid].name);
7468 if (cmp < 0)
7469 hi = mid;
7470 else if (cmp > 0)
7471 lo = mid + 1;
7472 else {
7473 *valuep = table[mid].value;
7474 return 1;
7475 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007476 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007477 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007478 }
7479 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007480 PyErr_SetString(PyExc_TypeError,
7481 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007482 return 0;
7483}
7484
7485
7486#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7487static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007488#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007489 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007490#endif
7491#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007492 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007493#endif
Fred Drakec9680921999-12-13 16:37:25 +00007494#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007495 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007496#endif
7497#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007498 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007499#endif
7500#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007501 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007502#endif
7503#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007504 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007505#endif
7506#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007507 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007508#endif
7509#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007510 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007511#endif
7512#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007513 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007514#endif
7515#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007516 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007517#endif
7518#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007519 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007520#endif
7521#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007522 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007523#endif
7524#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007525 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007526#endif
7527#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007528 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007529#endif
7530#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007531 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007532#endif
7533#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007534 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007535#endif
7536#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007537 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007538#endif
7539};
7540
Fred Drakec9680921999-12-13 16:37:25 +00007541static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007542conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007543{
7544 return conv_confname(arg, valuep, posix_constants_pathconf,
7545 sizeof(posix_constants_pathconf)
7546 / sizeof(struct constdef));
7547}
7548#endif
7549
7550#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007551PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007552"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007553Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007554If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007555
7556static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007557posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007558{
7559 PyObject *result = NULL;
7560 int name, fd;
7561
Fred Drake12c6e2d1999-12-14 21:25:03 +00007562 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7563 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007564 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007565
Stefan Krah93f7a322010-11-26 17:35:50 +00007566 errno = 0;
7567 limit = fpathconf(fd, name);
7568 if (limit == -1 && errno != 0)
7569 posix_error();
7570 else
7571 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007572 }
7573 return result;
7574}
7575#endif
7576
7577
7578#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007579PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007580"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007581Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007582If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007583
7584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007585posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007586{
7587 PyObject *result = NULL;
7588 int name;
7589 char *path;
7590
7591 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7592 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007593 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007594
Victor Stinnerd6f85422010-05-05 23:33:33 +00007595 errno = 0;
7596 limit = pathconf(path, name);
7597 if (limit == -1 && errno != 0) {
7598 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007599 /* could be a path or name problem */
7600 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007601 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007602 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007603 }
7604 else
7605 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007606 }
7607 return result;
7608}
7609#endif
7610
7611#ifdef HAVE_CONFSTR
7612static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007613#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007614 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007615#endif
7616#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007617 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007618#endif
7619#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007620 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007621#endif
7622#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007623 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007624#endif
7625#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007626 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007627#endif
Fred Drakec9680921999-12-13 16:37:25 +00007628#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007629 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007630#endif
7631#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007632 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007633#endif
7634#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007635 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007636#endif
7637#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007638 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007639#endif
7640#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007641 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007642#endif
7643#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007644 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007645#endif
7646#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007647 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007648#endif
7649#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007650 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007651#endif
Fred Draked86ed291999-12-15 15:34:33 +00007652#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007653 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007654#endif
Fred Drakec9680921999-12-13 16:37:25 +00007655#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007656 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007657#endif
Fred Draked86ed291999-12-15 15:34:33 +00007658#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007659 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007660#endif
7661#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007662 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007663#endif
7664#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007665 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007666#endif
7667#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007668 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007669#endif
Fred Drakec9680921999-12-13 16:37:25 +00007670#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007671 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007672#endif
7673#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007674 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007675#endif
7676#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007677 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007678#endif
7679#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007680 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007681#endif
7682#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007683 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007684#endif
7685#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007686 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007687#endif
7688#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007689 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007690#endif
7691#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007692 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007693#endif
7694#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007696#endif
7697#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007698 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007699#endif
7700#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007701 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007702#endif
7703#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007704 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007705#endif
7706#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007708#endif
7709#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007711#endif
7712#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007713 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007714#endif
7715#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007716 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007717#endif
Fred Draked86ed291999-12-15 15:34:33 +00007718#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007719 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007720#endif
7721#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007722 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007723#endif
7724#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007725 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007726#endif
7727#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007728 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007729#endif
7730#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007731 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007732#endif
7733#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007735#endif
7736#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007737 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007738#endif
7739#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007740 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007741#endif
7742#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007743 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007744#endif
7745#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007746 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007747#endif
7748#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007749 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007750#endif
7751#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007752 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007753#endif
7754#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007755 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007756#endif
Fred Drakec9680921999-12-13 16:37:25 +00007757};
7758
7759static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007760conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007761{
7762 return conv_confname(arg, valuep, posix_constants_confstr,
7763 sizeof(posix_constants_confstr)
7764 / sizeof(struct constdef));
7765}
7766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007767PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007768"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007769Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007770
7771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007772posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007773{
7774 PyObject *result = NULL;
7775 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007776 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007777
7778 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007779 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007780
Victor Stinnerd6f85422010-05-05 23:33:33 +00007781 errno = 0;
7782 len = confstr(name, buffer, sizeof(buffer));
7783 if (len == 0) {
7784 if (errno) {
7785 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007786 }
7787 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007788 result = Py_None;
7789 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007790 }
7791 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007792 else {
7793 if ((unsigned int)len >= sizeof(buffer)) {
7794 result = PyString_FromStringAndSize(NULL, len-1);
7795 if (result != NULL)
7796 confstr(name, PyString_AS_STRING(result), len);
7797 }
7798 else
7799 result = PyString_FromStringAndSize(buffer, len-1);
7800 }
7801 }
Fred Drakec9680921999-12-13 16:37:25 +00007802 return result;
7803}
7804#endif
7805
7806
7807#ifdef HAVE_SYSCONF
7808static struct constdef posix_constants_sysconf[] = {
7809#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007810 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007811#endif
7812#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007814#endif
7815#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007816 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007817#endif
7818#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007819 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007820#endif
7821#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007822 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007823#endif
7824#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007825 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007826#endif
7827#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007828 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007829#endif
7830#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007831 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007832#endif
7833#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007834 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007835#endif
7836#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007837 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007838#endif
Fred Draked86ed291999-12-15 15:34:33 +00007839#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007840 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007841#endif
7842#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007843 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007844#endif
Fred Drakec9680921999-12-13 16:37:25 +00007845#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007846 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007847#endif
Fred Drakec9680921999-12-13 16:37:25 +00007848#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007850#endif
7851#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007853#endif
7854#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007856#endif
7857#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007859#endif
7860#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007862#endif
Fred Draked86ed291999-12-15 15:34:33 +00007863#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007865#endif
Fred Drakec9680921999-12-13 16:37:25 +00007866#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
7869#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
Fred Draked86ed291999-12-15 15:34:33 +00007881#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007883#endif
Fred Drakec9680921999-12-13 16:37:25 +00007884#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007886#endif
7887#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007889#endif
7890#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007892#endif
7893#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007895#endif
7896#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007898#endif
7899#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007901#endif
7902#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007904#endif
7905#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
7908#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007910#endif
7911#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007913#endif
7914#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007916#endif
7917#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
7920#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007922#endif
7923#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
7926#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007928#endif
7929#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007931#endif
7932#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007934#endif
7935#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007937#endif
7938#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007940#endif
7941#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007943#endif
7944#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007946#endif
7947#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007949#endif
7950#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007951 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007952#endif
Fred Draked86ed291999-12-15 15:34:33 +00007953#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007954 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007955#endif
Fred Drakec9680921999-12-13 16:37:25 +00007956#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007957 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007958#endif
7959#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007960 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007961#endif
7962#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007963 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007964#endif
Fred Draked86ed291999-12-15 15:34:33 +00007965#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007966 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007967#endif
Fred Drakec9680921999-12-13 16:37:25 +00007968#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007969 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007970#endif
Fred Draked86ed291999-12-15 15:34:33 +00007971#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007973#endif
7974#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007975 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007976#endif
Fred Drakec9680921999-12-13 16:37:25 +00007977#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007979#endif
7980#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007982#endif
7983#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007984 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007985#endif
7986#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007987 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007988#endif
Fred Draked86ed291999-12-15 15:34:33 +00007989#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007990 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007991#endif
Fred Drakec9680921999-12-13 16:37:25 +00007992#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007993 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007994#endif
7995#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007996 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007997#endif
7998#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007999 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008000#endif
8001#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008002 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00008003#endif
8004#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008005 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00008006#endif
8007#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008008 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008009#endif
8010#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008011 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008012#endif
Fred Draked86ed291999-12-15 15:34:33 +00008013#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008014 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008015#endif
Fred Drakec9680921999-12-13 16:37:25 +00008016#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008017 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008018#endif
8019#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008020 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008021#endif
Fred Draked86ed291999-12-15 15:34:33 +00008022#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008023 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008024#endif
Fred Drakec9680921999-12-13 16:37:25 +00008025#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008026 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008027#endif
8028#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008029 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008030#endif
8031#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008032 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008033#endif
8034#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008035 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008036#endif
8037#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008038 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008039#endif
8040#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008041 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008042#endif
8043#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008044 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008045#endif
8046#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008047 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008048#endif
8049#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008050 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008051#endif
Fred Draked86ed291999-12-15 15:34:33 +00008052#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008053 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008054#endif
8055#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008056 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008057#endif
Fred Drakec9680921999-12-13 16:37:25 +00008058#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008059 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008060#endif
8061#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008062 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
8064#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008065 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008066#endif
8067#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008068 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008069#endif
8070#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008071 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008072#endif
8073#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008074 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008075#endif
8076#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008077 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008078#endif
8079#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008080 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
8082#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008083 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008084#endif
8085#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008086 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008087#endif
8088#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008089 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008090#endif
8091#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008092 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008093#endif
8094#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008095 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008096#endif
8097#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008098 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008099#endif
8100#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008101 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008102#endif
8103#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008104 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008105#endif
8106#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008107 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008108#endif
8109#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008110 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008111#endif
8112#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008113 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008114#endif
8115#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008116 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008117#endif
8118#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008119 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008120#endif
8121#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008122 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008123#endif
8124#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008125 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008126#endif
8127#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008128 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008129#endif
8130#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008131 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008132#endif
8133#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008134 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008135#endif
8136#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008137 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008138#endif
8139#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008140 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008141#endif
8142#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008143 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008144#endif
8145#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008146 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008147#endif
8148#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008149 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008150#endif
8151#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008152 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008153#endif
8154#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008155 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008156#endif
8157#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008158 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008159#endif
8160#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008161 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008162#endif
Fred Draked86ed291999-12-15 15:34:33 +00008163#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008164 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008165#endif
Fred Drakec9680921999-12-13 16:37:25 +00008166#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008167 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008168#endif
8169#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008170 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008171#endif
8172#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008173 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008174#endif
8175#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008176 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008177#endif
8178#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008179 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008180#endif
8181#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008182 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008183#endif
8184#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008185 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008186#endif
8187#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008188 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008189#endif
8190#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008191 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008192#endif
8193#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008194 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008195#endif
8196#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008197 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008198#endif
8199#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008200 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008201#endif
8202#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008203 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008204#endif
8205#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008206 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008207#endif
8208#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008209 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008210#endif
8211#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008212 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008213#endif
8214#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008215 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008218 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008221 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
8223#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008224 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008225#endif
8226#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008227 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008230 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
8232#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008233 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008234#endif
8235#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008236 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008239 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008242 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008245 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
8247#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008248 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008251 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008254 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008257 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008258#endif
8259#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008260 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008261#endif
8262#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008263 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008264#endif
8265#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008266 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008267#endif
8268#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008269 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008270#endif
8271#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008272 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008273#endif
8274#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008275 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008276#endif
8277#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008278 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008279#endif
8280#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008281 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008282#endif
8283#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008284 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008285#endif
8286#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008287 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008288#endif
8289#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008290 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008291#endif
8292#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008293 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008294#endif
8295#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008296 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008297#endif
8298#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008299 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008300#endif
8301};
8302
8303static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008304conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008305{
8306 return conv_confname(arg, valuep, posix_constants_sysconf,
8307 sizeof(posix_constants_sysconf)
8308 / sizeof(struct constdef));
8309}
8310
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008311PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008312"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008313Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008314
8315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008316posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008317{
8318 PyObject *result = NULL;
8319 int name;
8320
8321 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008322 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008323
Victor Stinner862490a2010-05-06 00:03:44 +00008324 errno = 0;
8325 value = sysconf(name);
8326 if (value == -1 && errno != 0)
8327 posix_error();
8328 else
8329 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008330 }
8331 return result;
8332}
8333#endif
8334
8335
Fred Drakebec628d1999-12-15 18:31:10 +00008336/* This code is used to ensure that the tables of configuration value names
8337 * are in sorted order as required by conv_confname(), and also to build the
8338 * the exported dictionaries that are used to publish information about the
8339 * names available on the host platform.
8340 *
8341 * Sorting the table at runtime ensures that the table is properly ordered
8342 * when used, even for platforms we're not able to test on. It also makes
8343 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008344 */
Fred Drakebec628d1999-12-15 18:31:10 +00008345
8346static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008347cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008348{
8349 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008350 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008351 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008352 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008353
8354 return strcmp(c1->name, c2->name);
8355}
8356
8357static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008358setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008359 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008360{
Fred Drakebec628d1999-12-15 18:31:10 +00008361 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008362 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008363
8364 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8365 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008366 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008367 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008368
Barry Warsaw3155db32000-04-13 15:20:40 +00008369 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008370 PyObject *o = PyInt_FromLong(table[i].value);
8371 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8372 Py_XDECREF(o);
8373 Py_DECREF(d);
8374 return -1;
8375 }
8376 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008377 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008378 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008379}
8380
Fred Drakebec628d1999-12-15 18:31:10 +00008381/* Return -1 on failure, 0 on success. */
8382static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008383setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008384{
8385#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008386 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008387 sizeof(posix_constants_pathconf)
8388 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008389 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008390 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008391#endif
8392#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008393 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008394 sizeof(posix_constants_confstr)
8395 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008396 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008397 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008398#endif
8399#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008400 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008401 sizeof(posix_constants_sysconf)
8402 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008403 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008404 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008405#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008406 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008407}
Fred Draked86ed291999-12-15 15:34:33 +00008408
8409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008410PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008411"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008412Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008413in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008414
8415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008416posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008417{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008418 abort();
8419 /*NOTREACHED*/
8420 Py_FatalError("abort() called from Python code didn't abort!");
8421 return NULL;
8422}
Fred Drakebec628d1999-12-15 18:31:10 +00008423
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008424#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008425PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008426"startfile(filepath [, operation]) - Start a file with its associated\n\
8427application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008428\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008429When \"operation\" is not specified or \"open\", this acts like\n\
8430double-clicking the file in Explorer, or giving the file name as an\n\
8431argument to the DOS \"start\" command: the file is opened with whatever\n\
8432application (if any) its extension is associated.\n\
8433When another \"operation\" is given, it specifies what should be done with\n\
8434the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008435\n\
8436startfile returns as soon as the associated application is launched.\n\
8437There is no option to wait for the application to close, and no way\n\
8438to retrieve the application's exit status.\n\
8439\n\
8440The filepath is relative to the current directory. If you want to use\n\
8441an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008442the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008443
8444static PyObject *
8445win32_startfile(PyObject *self, PyObject *args)
8446{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008447 char *filepath;
8448 char *operation = NULL;
8449 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008450
Victor Stinnerd6f85422010-05-05 23:33:33 +00008451 PyObject *unipath, *woperation = NULL;
8452 if (!PyArg_ParseTuple(args, "U|s:startfile",
8453 &unipath, &operation)) {
8454 PyErr_Clear();
8455 goto normal;
8456 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008457
Victor Stinnerd6f85422010-05-05 23:33:33 +00008458 if (operation) {
8459 woperation = PyUnicode_DecodeASCII(operation,
8460 strlen(operation), NULL);
8461 if (!woperation) {
8462 PyErr_Clear();
8463 operation = NULL;
8464 goto normal;
8465 }
8466 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008467
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 Py_BEGIN_ALLOW_THREADS
8469 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8470 PyUnicode_AS_UNICODE(unipath),
8471 NULL, NULL, SW_SHOWNORMAL);
8472 Py_END_ALLOW_THREADS
8473
8474 Py_XDECREF(woperation);
8475 if (rc <= (HINSTANCE)32) {
8476 PyObject *errval = win32_error_unicode("startfile",
8477 PyUnicode_AS_UNICODE(unipath));
8478 return errval;
8479 }
8480 Py_INCREF(Py_None);
8481 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008482
8483normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008484 if (!PyArg_ParseTuple(args, "et|s:startfile",
8485 Py_FileSystemDefaultEncoding, &filepath,
8486 &operation))
8487 return NULL;
8488 Py_BEGIN_ALLOW_THREADS
8489 rc = ShellExecute((HWND)0, operation, filepath,
8490 NULL, NULL, SW_SHOWNORMAL);
8491 Py_END_ALLOW_THREADS
8492 if (rc <= (HINSTANCE)32) {
8493 PyObject *errval = win32_error("startfile", filepath);
8494 PyMem_Free(filepath);
8495 return errval;
8496 }
8497 PyMem_Free(filepath);
8498 Py_INCREF(Py_None);
8499 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008500}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008501#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008502
Martin v. Löwis438b5342002-12-27 10:16:42 +00008503#ifdef HAVE_GETLOADAVG
8504PyDoc_STRVAR(posix_getloadavg__doc__,
8505"getloadavg() -> (float, float, float)\n\n\
8506Return the number of processes in the system run queue averaged over\n\
8507the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8508was unobtainable");
8509
8510static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008511posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008512{
8513 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008514 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008515 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8516 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008517 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008518 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008519}
8520#endif
8521
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008522#ifdef MS_WINDOWS
8523
8524PyDoc_STRVAR(win32_urandom__doc__,
8525"urandom(n) -> str\n\n\
8526Return a string of n random bytes suitable for cryptographic use.");
8527
8528typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8529 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8530 DWORD dwFlags );
8531typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8532 BYTE *pbBuffer );
8533
8534static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008535/* This handle is never explicitly released. Instead, the operating
8536 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008537static HCRYPTPROV hCryptProv = 0;
8538
Tim Peters4ad82172004-08-30 17:02:04 +00008539static PyObject*
8540win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008541{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008542 int howMany;
8543 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008544
Victor Stinnerd6f85422010-05-05 23:33:33 +00008545 /* Read arguments */
8546 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8547 return NULL;
8548 if (howMany < 0)
8549 return PyErr_Format(PyExc_ValueError,
8550 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008551
Victor Stinnerd6f85422010-05-05 23:33:33 +00008552 if (hCryptProv == 0) {
8553 HINSTANCE hAdvAPI32 = NULL;
8554 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008555
Victor Stinnerd6f85422010-05-05 23:33:33 +00008556 /* Obtain handle to the DLL containing CryptoAPI
8557 This should not fail */
8558 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8559 if(hAdvAPI32 == NULL)
8560 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008561
Victor Stinnerd6f85422010-05-05 23:33:33 +00008562 /* Obtain pointers to the CryptoAPI functions
8563 This will fail on some early versions of Win95 */
8564 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8565 hAdvAPI32,
8566 "CryptAcquireContextA");
8567 if (pCryptAcquireContext == NULL)
8568 return PyErr_Format(PyExc_NotImplementedError,
8569 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008570
Victor Stinnerd6f85422010-05-05 23:33:33 +00008571 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8572 hAdvAPI32, "CryptGenRandom");
8573 if (pCryptGenRandom == NULL)
8574 return PyErr_Format(PyExc_NotImplementedError,
8575 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008576
Victor Stinnerd6f85422010-05-05 23:33:33 +00008577 /* Acquire context */
8578 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8579 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8580 return win32_error("CryptAcquireContext", NULL);
8581 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008582
Victor Stinnerd6f85422010-05-05 23:33:33 +00008583 /* Allocate bytes */
8584 result = PyString_FromStringAndSize(NULL, howMany);
8585 if (result != NULL) {
8586 /* Get random data */
8587 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8588 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8589 PyString_AS_STRING(result))) {
8590 Py_DECREF(result);
8591 return win32_error("CryptGenRandom", NULL);
8592 }
8593 }
8594 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008595}
8596#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008597
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008598#ifdef __VMS
8599/* Use openssl random routine */
8600#include <openssl/rand.h>
8601PyDoc_STRVAR(vms_urandom__doc__,
8602"urandom(n) -> str\n\n\
8603Return a string of n random bytes suitable for cryptographic use.");
8604
8605static PyObject*
8606vms_urandom(PyObject *self, PyObject *args)
8607{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008608 int howMany;
8609 PyObject* result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008610
Victor Stinnerd6f85422010-05-05 23:33:33 +00008611 /* Read arguments */
8612 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8613 return NULL;
8614 if (howMany < 0)
8615 return PyErr_Format(PyExc_ValueError,
8616 "negative argument not allowed");
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008617
Victor Stinnerd6f85422010-05-05 23:33:33 +00008618 /* Allocate bytes */
8619 result = PyString_FromStringAndSize(NULL, howMany);
8620 if (result != NULL) {
8621 /* Get random data */
8622 if (RAND_pseudo_bytes((unsigned char*)
8623 PyString_AS_STRING(result),
8624 howMany) < 0) {
8625 Py_DECREF(result);
8626 return PyErr_Format(PyExc_ValueError,
8627 "RAND_pseudo_bytes");
8628 }
8629 }
8630 return result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008631}
8632#endif
8633
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008634#ifdef HAVE_SETRESUID
8635PyDoc_STRVAR(posix_setresuid__doc__,
8636"setresuid(ruid, euid, suid)\n\n\
8637Set the current process's real, effective, and saved user ids.");
8638
8639static PyObject*
8640posix_setresuid (PyObject *self, PyObject *args)
8641{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008642 /* We assume uid_t is no larger than a long. */
8643 long ruid, euid, suid;
8644 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8645 return NULL;
8646 if (setresuid(ruid, euid, suid) < 0)
8647 return posix_error();
8648 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008649}
8650#endif
8651
8652#ifdef HAVE_SETRESGID
8653PyDoc_STRVAR(posix_setresgid__doc__,
8654"setresgid(rgid, egid, sgid)\n\n\
8655Set the current process's real, effective, and saved group ids.");
8656
8657static PyObject*
8658posix_setresgid (PyObject *self, PyObject *args)
8659{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008660 /* We assume uid_t is no larger than a long. */
8661 long rgid, egid, sgid;
8662 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8663 return NULL;
8664 if (setresgid(rgid, egid, sgid) < 0)
8665 return posix_error();
8666 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008667}
8668#endif
8669
8670#ifdef HAVE_GETRESUID
8671PyDoc_STRVAR(posix_getresuid__doc__,
8672"getresuid() -> (ruid, euid, suid)\n\n\
8673Get tuple of the current process's real, effective, and saved user ids.");
8674
8675static PyObject*
8676posix_getresuid (PyObject *self, PyObject *noargs)
8677{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008678 uid_t ruid, euid, suid;
8679 long l_ruid, l_euid, l_suid;
8680 if (getresuid(&ruid, &euid, &suid) < 0)
8681 return posix_error();
8682 /* Force the values into long's as we don't know the size of uid_t. */
8683 l_ruid = ruid;
8684 l_euid = euid;
8685 l_suid = suid;
8686 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008687}
8688#endif
8689
8690#ifdef HAVE_GETRESGID
8691PyDoc_STRVAR(posix_getresgid__doc__,
8692"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008693Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008694
8695static PyObject*
8696posix_getresgid (PyObject *self, PyObject *noargs)
8697{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008698 uid_t rgid, egid, sgid;
8699 long l_rgid, l_egid, l_sgid;
8700 if (getresgid(&rgid, &egid, &sgid) < 0)
8701 return posix_error();
8702 /* Force the values into long's as we don't know the size of uid_t. */
8703 l_rgid = rgid;
8704 l_egid = egid;
8705 l_sgid = sgid;
8706 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008707}
8708#endif
8709
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008710static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008711 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008712#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008713 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008714#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008715 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008716#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008717 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008718#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008719 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008720#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008721 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008722#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008723#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008724 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008725#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008726#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008727 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008728#endif /* HAVE_LCHMOD */
8729#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008730 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008731#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008732#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008733 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008734#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008735#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008736 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008737#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008738#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008739 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008740#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008741#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008742 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008743#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008744#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008745 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008746#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008747 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008748#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008749#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008750#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008751 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008752#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008753 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8754 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8755 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008756#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008757 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008758#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008759#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008760 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008761#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008762 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8763 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8764 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8765 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008766#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008767 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008768#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008769#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008770 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008771#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008772 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008773#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008774 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008775#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008776 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8777 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8778 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008779#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008780 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008781#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008782 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008783#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008784 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8785 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008786#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008787#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008788 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8789 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008790#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008791 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8792 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008793#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008794#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008795#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008796 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008797#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008798#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008799 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008800#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008801#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008802 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008803#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008804#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008805 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008806#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008807#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008808 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008809#endif /* HAVE_GETEGID */
8810#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008811 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008812#endif /* HAVE_GETEUID */
8813#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008814 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008815#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008816#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008817 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008818#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008819 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008820#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008821 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008822#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008823#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008824 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008825#endif /* HAVE_GETPPID */
8826#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008828#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008829#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008830 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008831#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008832#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008834#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008835#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008837#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008838#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008839 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008840#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008841#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008842 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008843#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008844 {"popen2", win32_popen2, METH_VARARGS},
8845 {"popen3", win32_popen3, METH_VARARGS},
8846 {"popen4", win32_popen4, METH_VARARGS},
8847 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8848 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008849#else
8850#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 {"popen2", os2emx_popen2, METH_VARARGS},
8852 {"popen3", os2emx_popen3, METH_VARARGS},
8853 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008854#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008855#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008856#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008857#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008858 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008859#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008860#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008862#endif /* HAVE_SETEUID */
8863#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008864 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008865#endif /* HAVE_SETEGID */
8866#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008867 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008868#endif /* HAVE_SETREUID */
8869#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008870 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008871#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008872#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008873 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008874#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008875#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008876 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008877#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008878#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008879 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008880#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008881#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008883#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008884#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008885 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008886#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008887#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008888 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008889#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008890#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008891 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008892#endif /* HAVE_WAIT3 */
8893#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008894 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008895#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008896#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008897 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008898#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008899#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008900 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008901#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008902#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008903 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008904#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008905#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008906 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008907#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008908#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008909 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008910#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008911#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008912 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008913#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008914 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8915 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8916 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8917 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8918 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8919 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8920 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8921 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8922 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8923 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8924 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008925#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008926 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008927#endif
8928#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008930#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008931#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008933#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008934#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8936 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8937 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008938#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008939#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008940 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008941#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008942#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008943 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008944#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008945#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008946 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008947#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008949#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008950 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008951#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008952#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008953 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008954#endif
8955#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008956 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008957#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008958#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008959#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008960 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008961#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008962#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008964#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008965#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008966 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008967#endif /* WIFSTOPPED */
8968#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008969 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008970#endif /* WIFSIGNALED */
8971#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008972 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008973#endif /* WIFEXITED */
8974#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008975 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008976#endif /* WEXITSTATUS */
8977#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008978 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008979#endif /* WTERMSIG */
8980#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008981 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008982#endif /* WSTOPSIG */
8983#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008984#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008985 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008986#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008987#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008988 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008989#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008990#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008991 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008992#endif
8993#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008994 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008995#endif
8996#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008997 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008998#endif
Fred Drakec9680921999-12-13 16:37:25 +00008999#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009000 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009001#endif
9002#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009003 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009004#endif
9005#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009006 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009007#endif
9008#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009009 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009010#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009011 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009012#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009013 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin5446f082011-06-09 10:00:42 -05009014 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00009015#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009016#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009017 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009018#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009019 #ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009020 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009021 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00009022 #ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009023 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Neal Norwitz2a30cd02006-07-10 01:18:57 +00009024 #endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009025#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009026 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009027#endif
9028#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009029 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009030#endif
9031#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009032 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009033#endif
9034#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009035 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009036#endif
9037
Victor Stinnerd6f85422010-05-05 23:33:33 +00009038 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009039};
9040
9041
Barry Warsaw4a342091996-12-19 23:50:02 +00009042static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009043ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009044{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009045 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009046}
9047
Guido van Rossumd48f2521997-12-05 22:19:34 +00009048#if defined(PYOS_OS2)
9049/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009050static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009051{
9052 APIRET rc;
9053 ULONG values[QSV_MAX+1];
9054 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009055 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009056
9057 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009058 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009059 Py_END_ALLOW_THREADS
9060
9061 if (rc != NO_ERROR) {
9062 os2_error(rc);
9063 return -1;
9064 }
9065
Fred Drake4d1e64b2002-04-15 19:40:07 +00009066 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9067 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9068 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9069 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9070 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9071 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9072 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009073
9074 switch (values[QSV_VERSION_MINOR]) {
9075 case 0: ver = "2.00"; break;
9076 case 10: ver = "2.10"; break;
9077 case 11: ver = "2.11"; break;
9078 case 30: ver = "3.00"; break;
9079 case 40: ver = "4.00"; break;
9080 case 50: ver = "5.00"; break;
9081 default:
Tim Peters885d4572001-11-28 20:27:42 +00009082 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009083 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009084 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009085 ver = &tmp[0];
9086 }
9087
9088 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009089 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009090 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009091
9092 /* Add Indicator of Which Drive was Used to Boot the System */
9093 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9094 tmp[1] = ':';
9095 tmp[2] = '\0';
9096
Fred Drake4d1e64b2002-04-15 19:40:07 +00009097 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009098}
9099#endif
9100
Barry Warsaw4a342091996-12-19 23:50:02 +00009101static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009102all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009103{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009104#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009105 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009106#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009107#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009108 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009109#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009110#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009111 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009112#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009113#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009114 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009115#endif
Fred Drakec9680921999-12-13 16:37:25 +00009116#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009117 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009118#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009119#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009120 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009121#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009122#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009123 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009124#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009125#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009126 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009127#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009128#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009129 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009130#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009131#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009132 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009133#endif
9134#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009135 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009136#endif
9137#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009138 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009139#endif
9140#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009141 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009142#endif
9143#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009144 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009145#endif
9146#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009147 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009148#endif
9149#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009150 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009151#endif
9152#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009153 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009154#endif
9155#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009156 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009157#endif
9158#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009159 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009160#endif
9161#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009162 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009163#endif
9164#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009165 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009166#endif
9167#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009168 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009169#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009170#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009171 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009172#endif
9173#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009174 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009175#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009176#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009177 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009178#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009179#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009180 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009181#endif
9182#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009183 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009184#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009185
Tim Peters5aa91602002-01-30 05:46:57 +00009186/* MS Windows */
9187#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009188 /* Don't inherit in child processes. */
9189 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009190#endif
9191#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009192 /* Optimize for short life (keep in memory). */
9193 /* MS forgot to define this one with a non-underscore form too. */
9194 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009195#endif
9196#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009197 /* Automatically delete when last handle is closed. */
9198 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009199#endif
9200#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009201 /* Optimize for random access. */
9202 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009203#endif
9204#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009205 /* Optimize for sequential access. */
9206 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009207#endif
9208
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009209/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009210#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009211 /* Send a SIGIO signal whenever input or output
9212 becomes available on file descriptor */
9213 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009214#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009215#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009216 /* Direct disk access. */
9217 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009218#endif
9219#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009220 /* Must be a directory. */
9221 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009222#endif
9223#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009224 /* Do not follow links. */
9225 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009226#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009227#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009228 /* Do not update the access time. */
9229 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009230#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009231
Victor Stinnerd6f85422010-05-05 23:33:33 +00009232 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009233#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009234 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009235#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009236#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009237 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009238#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009239#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009240 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009241#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009242#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009243 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009244#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009245#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009246 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009247#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009248#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009249 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009250#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009251#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009253#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009254#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009255 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009256#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009257#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009258 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009259#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009260#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009262#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009263#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009264 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009265#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009266#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009267 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009268#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009269#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009270 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009271#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009272#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009273 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009274#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009275#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009276 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009277#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009278#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009279 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009280#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009281#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009282 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009283#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009284
Guido van Rossum246bc171999-02-01 23:54:31 +00009285#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009286#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009287 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9288 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9289 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9290 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9291 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9292 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9293 if (ins(d, "P_PM", (long)P_PM)) return -1;
9294 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9295 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9296 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9297 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9298 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9299 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9300 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9301 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9302 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9303 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9304 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9305 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9306 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009307#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009308 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9309 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9310 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9311 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9312 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009313#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009314#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009315
Guido van Rossumd48f2521997-12-05 22:19:34 +00009316#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009317 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009318#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009319 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009320}
9321
9322
Tim Peters5aa91602002-01-30 05:46:57 +00009323#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009324#define INITFUNC initnt
9325#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009326
9327#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009328#define INITFUNC initos2
9329#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009330
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009331#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009332#define INITFUNC initposix
9333#define MODNAME "posix"
9334#endif
9335
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009336PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009337INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009338{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009340
Victor Stinnerd6f85422010-05-05 23:33:33 +00009341 m = Py_InitModule3(MODNAME,
9342 posix_methods,
9343 posix__doc__);
9344 if (m == NULL)
9345 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009346
Victor Stinnerd6f85422010-05-05 23:33:33 +00009347 /* Initialize environ dictionary */
9348 v = convertenviron();
9349 Py_XINCREF(v);
9350 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9351 return;
9352 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009353
Victor Stinnerd6f85422010-05-05 23:33:33 +00009354 if (all_ins(m))
9355 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009356
Victor Stinnerd6f85422010-05-05 23:33:33 +00009357 if (setup_confname_tables(m))
9358 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009359
Victor Stinnerd6f85422010-05-05 23:33:33 +00009360 Py_INCREF(PyExc_OSError);
9361 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009362
Guido van Rossumb3d39562000-01-31 18:41:26 +00009363#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009364 if (posix_putenv_garbage == NULL)
9365 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009366#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009367
Victor Stinnerd6f85422010-05-05 23:33:33 +00009368 if (!initialized) {
9369 stat_result_desc.name = MODNAME ".stat_result";
9370 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9371 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9372 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9373 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9374 structseq_new = StatResultType.tp_new;
9375 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009376
Victor Stinnerd6f85422010-05-05 23:33:33 +00009377 statvfs_result_desc.name = MODNAME ".statvfs_result";
9378 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009379#ifdef NEED_TICKS_PER_SECOND
9380# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009381 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009382# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009383 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009384# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009385 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009386# endif
9387#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009388 }
9389 Py_INCREF((PyObject*) &StatResultType);
9390 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9391 Py_INCREF((PyObject*) &StatVFSResultType);
9392 PyModule_AddObject(m, "statvfs_result",
9393 (PyObject*) &StatVFSResultType);
9394 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009395
9396#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009397 /*
9398 * Step 2 of weak-linking support on Mac OS X.
9399 *
9400 * The code below removes functions that are not available on the
9401 * currently active platform.
9402 *
9403 * This block allow one to use a python binary that was build on
9404 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9405 * OSX 10.4.
9406 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009407#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009408 if (fstatvfs == NULL) {
9409 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9410 return;
9411 }
9412 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009413#endif /* HAVE_FSTATVFS */
9414
9415#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009416 if (statvfs == NULL) {
9417 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9418 return;
9419 }
9420 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009421#endif /* HAVE_STATVFS */
9422
9423# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009424 if (lchown == NULL) {
9425 if (PyObject_DelAttrString(m, "lchown") == -1) {
9426 return;
9427 }
9428 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009429#endif /* HAVE_LCHOWN */
9430
9431
9432#endif /* __APPLE__ */
9433
Guido van Rossumb6775db1994-08-01 11:34:53 +00009434}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009435
9436#ifdef __cplusplus
9437}
9438#endif
9439
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009440