blob: e5fdc5a46371c79c36fad95e7346556b1eac5e9b [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
Victor Stinnerd6f85422010-05-05 23:33:33 +000018 * Step 1 of support for weak-linking a number of symbols existing on
Ronald Oussorend06b6f22006-04-23 11:59:25 +000019 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000069#endif /* HAVE_SYS_TYPES_H */
70
71#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
Victor Stinnerd6f85422010-05-05 23:33:33 +000076#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000077#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000107#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000114#ifdef __BORLANDC__ /* Borland compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000120#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000121#define HAVE_WAIT 1
122#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000129#define HAVE_SYSTEM 1
130#define HAVE_CWAIT 1
131#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Victor Stinnerd6f85422010-05-05 23:33:33 +0000136#else /* all other compilers */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000155#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000156#define HAVE_WAIT 1
Victor Stinnerd6f85422010-05-05 23:33:33 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
Christian Heimes36281872007-11-30 21:11:28 +0000194/*#ifdef HAVE_FCHMOD
195extern int fchmod(int, mode_t);
196#endif*/
197/*#ifdef HAVE_LCHMOD
198extern int lchmod(const char *, mode_t);
199#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int chown(const char *, uid_t, gid_t);
201extern char *getcwd(char *, int);
202extern char *strerror(int);
203extern int link(const char *, const char *);
204extern int rename(const char *, const char *);
205extern int stat(const char *, struct stat *);
206extern int unlink(const char *);
207extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000210#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000215
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#ifdef HAVE_UTIME_H
219#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000222#ifdef HAVE_SYS_UTIME_H
223#include <sys/utime.h>
224#define HAVE_UTIME_H /* pretend we do for the rest of this file */
225#endif /* HAVE_SYS_UTIME_H */
226
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_SYS_TIMES_H
228#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230
231#ifdef HAVE_SYS_PARAM_H
232#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000233#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234
235#ifdef HAVE_SYS_UTSNAME_H
236#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000241#define NAMLEN(dirent) strlen((dirent)->d_name)
242#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000243#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000244#include <direct.h>
245#define NAMLEN(dirent) strlen((dirent)->d_name)
246#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000248#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000250#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#endif
256#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000258#endif
259#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000261#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000262#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
265#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000266#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000267#endif
268#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000270#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000271#include "osdefs.h"
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000272#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <windows.h>
Victor Stinnerd6f85422010-05-05 23:33:33 +0000274#include <shellapi.h> /* for ShellExecute() */
275#define popen _popen
276#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
Guido van Rossumd48f2521997-12-05 22:19:34 +0000279#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000281#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Tim Petersbc2e10e2002-03-03 23:17:02 +0000283#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000284#if defined(PATH_MAX) && PATH_MAX > 1024
285#define MAXPATHLEN PATH_MAX
286#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000287#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000288#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000289#endif /* MAXPATHLEN */
290
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000291#ifdef UNION_WAIT
292/* Emulate some macros on systems that have a union instead of macros */
293
294#ifndef WIFEXITED
295#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
296#endif
297
298#ifndef WEXITSTATUS
299#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
300#endif
301
302#ifndef WTERMSIG
303#define WTERMSIG(u_wait) ((u_wait).w_termsig)
304#endif
305
Neal Norwitzd5a37542006-03-20 06:48:34 +0000306#define WAIT_TYPE union wait
307#define WAIT_STATUS_INT(s) (s.w_status)
308
309#else /* !UNION_WAIT */
310#define WAIT_TYPE int
311#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000312#endif /* UNION_WAIT */
313
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000314/* Issue #1983: pid_t can be longer than a C long on some systems */
Antoine Pitrou4fe38582009-05-24 12:15:04 +0000315#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000316#define PARSE_PID "i"
317#define PyLong_FromPid PyInt_FromLong
318#define PyLong_AsPid PyInt_AsLong
319#elif SIZEOF_PID_T == SIZEOF_LONG
320#define PARSE_PID "l"
321#define PyLong_FromPid PyInt_FromLong
322#define PyLong_AsPid PyInt_AsLong
323#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
324#define PARSE_PID "L"
325#define PyLong_FromPid PyLong_FromLongLong
326#define PyLong_AsPid PyInt_AsLongLong
327#else
328#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
Antoine Pitrou5e858fe2009-05-23 15:37:45 +0000329#endif /* SIZEOF_PID_T */
330
Greg Wardb48bc172000-03-01 21:51:56 +0000331/* Don't use the "_r" form if we don't need it (also, won't have a
332 prototype for it, at least on Solaris -- maybe others as well?). */
333#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
334#define USE_CTERMID_R
335#endif
336
337#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
338#define USE_TMPNAM_R
339#endif
340
Fred Drake699f3522000-06-29 21:12:41 +0000341/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000342#undef STAT
Antoine Pitrou63a3f152011-01-19 15:27:24 +0000343#undef FSTAT
344#undef STRUCT_STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000345#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000346# define STAT win32_stat
347# define FSTAT win32_fstat
348# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000349#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000350# define STAT stat
351# define FSTAT fstat
352# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000353#endif
354
Tim Peters11b23062003-04-23 02:39:17 +0000355#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000356#include <sys/mkdev.h>
357#else
358#if defined(MAJOR_IN_SYSMACROS)
359#include <sys/sysmacros.h>
360#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000361#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
362#include <sys/mkdev.h>
363#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#endif
Fred Drake699f3522000-06-29 21:12:41 +0000365
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000366#if defined _MSC_VER && _MSC_VER >= 1400
367/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
368 * valid and throw an assertion if it isn't.
369 * Normally, an invalid fd is likely to be a C program error and therefore
370 * an assertion can be useful, but it does contradict the POSIX standard
371 * which for write(2) states:
372 * "Otherwise, -1 shall be returned and errno set to indicate the error."
373 * "[EBADF] The fildes argument is not a valid file descriptor open for
374 * writing."
375 * Furthermore, python allows the user to enter any old integer
376 * as a fd and should merely raise a python exception on error.
377 * The Microsoft CRT doesn't provide an official way to check for the
378 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000379 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000380 * internal structures involved.
381 * The structures below must be updated for each version of visual studio
382 * according to the file internal.h in the CRT source, until MS comes
383 * up with a less hacky way to do this.
384 * (all of this is to avoid globally modifying the CRT behaviour using
385 * _set_invalid_parameter_handler() and _CrtSetReportMode())
386 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000387/* The actual size of the structure is determined at runtime.
388 * Only the first items must be present.
389 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000390typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000391 intptr_t osfhnd;
392 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000393} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000394
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000395extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000396#define IOINFO_L2E 5
397#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
398#define IOINFO_ARRAYS 64
399#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
400#define FOPEN 0x01
401#define _NO_CONSOLE_FILENO (intptr_t)-2
402
403/* This function emulates what the windows CRT does to validate file handles */
404int
405_PyVerify_fd(int fd)
406{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000407 const int i1 = fd >> IOINFO_L2E;
408 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000409
Victor Stinnerd6f85422010-05-05 23:33:33 +0000410 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000411
Victor Stinnerd6f85422010-05-05 23:33:33 +0000412 /* Determine the actual size of the ioinfo structure,
413 * as used by the CRT loaded in memory
414 */
415 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
416 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
417 }
418 if (sizeof_ioinfo == 0) {
419 /* This should not happen... */
420 goto fail;
421 }
422
423 /* See that it isn't a special CLEAR fileno */
424 if (fd != _NO_CONSOLE_FILENO) {
425 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
426 * we check pointer validity and other info
427 */
428 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
429 /* finally, check that the file is open */
430 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
431 if (info->osfile & FOPEN) {
432 return 1;
433 }
434 }
435 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000436 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000437 errno = EBADF;
438 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000439}
440
441/* the special case of checking dup2. The target fd must be in a sensible range */
442static int
443_PyVerify_fd_dup2(int fd1, int fd2)
444{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000445 if (!_PyVerify_fd(fd1))
446 return 0;
447 if (fd2 == _NO_CONSOLE_FILENO)
448 return 0;
449 if ((unsigned)fd2 < _NHANDLE_)
450 return 1;
451 else
452 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000453}
454#else
455/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
456#define _PyVerify_fd_dup2(A, B) (1)
457#endif
458
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000460#ifdef WITH_NEXT_FRAMEWORK
461/* On Darwin/MacOSX a shared library or framework has no access to
462** environ directly, we must obtain it with _NSGetEnviron().
463*/
464#include <crt_externs.h>
465static char **environ;
466#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000468#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469
Barry Warsaw53699e91996-12-10 23:23:01 +0000470static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000471convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000472{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000473 PyObject *d;
474 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000475#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000476 APIRET rc;
477 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
478#endif
479 d = PyDict_New();
480 if (d == NULL)
481 return NULL;
482#ifdef WITH_NEXT_FRAMEWORK
483 if (environ == NULL)
484 environ = *_NSGetEnviron();
485#endif
486 if (environ == NULL)
487 return d;
488 /* This part ignores errors */
489 for (e = environ; *e != NULL; e++) {
490 PyObject *k;
491 PyObject *v;
492 char *p = strchr(*e, '=');
493 if (p == NULL)
494 continue;
495 k = PyString_FromStringAndSize(*e, (int)(p-*e));
496 if (k == NULL) {
497 PyErr_Clear();
498 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000499 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000500 v = PyString_FromString(p+1);
501 if (v == NULL) {
502 PyErr_Clear();
503 Py_DECREF(k);
504 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000505 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000506 if (PyDict_GetItem(d, k) == NULL) {
507 if (PyDict_SetItem(d, k, v) != 0)
508 PyErr_Clear();
509 }
510 Py_DECREF(k);
511 Py_DECREF(v);
512 }
513#if defined(PYOS_OS2)
514 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
515 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
516 PyObject *v = PyString_FromString(buffer);
517 PyDict_SetItemString(d, "BEGINLIBPATH", v);
518 Py_DECREF(v);
519 }
520 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
521 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
522 PyObject *v = PyString_FromString(buffer);
523 PyDict_SetItemString(d, "ENDLIBPATH", v);
524 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000525 }
526#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000527 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528}
529
530
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531/* Set a POSIX-specific error from errno, and return NULL */
532
Barry Warsawd58d7641998-07-23 16:14:40 +0000533static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000534posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000535{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000536 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537}
Barry Warsawd58d7641998-07-23 16:14:40 +0000538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000539posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000540{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000541 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000542}
543
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000544#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000545static PyObject *
546posix_error_with_unicode_filename(Py_UNICODE* name)
547{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000548 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000550#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551
552
Mark Hammondef8b6542001-05-13 08:04:26 +0000553static PyObject *
554posix_error_with_allocated_filename(char* name)
555{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000556 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
557 PyMem_Free(name);
558 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000559}
560
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000561#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000562static PyObject *
563win32_error(char* function, char* filename)
564{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000565 /* XXX We should pass the function name along in the future.
566 (_winreg.c also wants to pass the function name.)
567 This would however require an additional param to the
568 Windows error object, which is non-trivial.
569 */
570 errno = GetLastError();
571 if (filename)
572 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
573 else
574 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000575}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000576
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577static PyObject *
578win32_error_unicode(char* function, Py_UNICODE* filename)
579{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000580 /* XXX - see win32_error for comments on 'function' */
581 errno = GetLastError();
582 if (filename)
583 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
584 else
585 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000586}
587
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000588static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000589convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000590{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000591 if (PyUnicode_CheckExact(*param))
592 Py_INCREF(*param);
593 else if (PyUnicode_Check(*param))
594 /* For a Unicode subtype that's not a Unicode object,
595 return a true Unicode object with the same data. */
596 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
597 PyUnicode_GET_SIZE(*param));
598 else
599 *param = PyUnicode_FromEncodedObject(*param,
600 Py_FileSystemDefaultEncoding,
601 "strict");
602 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000603}
604
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000605#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606
Guido van Rossumd48f2521997-12-05 22:19:34 +0000607#if defined(PYOS_OS2)
608/**********************************************************************
609 * Helper Function to Trim and Format OS/2 Messages
610 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000611static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000612os2_formatmsg(char *msgbuf, int msglen, char *reason)
613{
614 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
615
616 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000617 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000618
Victor Stinner862490a2010-05-06 00:03:44 +0000619 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
620 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000621 }
622
623 /* Add Optional Reason Text */
624 if (reason) {
625 strcat(msgbuf, " : ");
626 strcat(msgbuf, reason);
627 }
628}
629
630/**********************************************************************
631 * Decode an OS/2 Operating System Error Code
632 *
633 * A convenience function to lookup an OS/2 error code and return a
634 * text message we can use to raise a Python exception.
635 *
636 * Notes:
637 * The messages for errors returned from the OS/2 kernel reside in
638 * the file OSO001.MSG in the \OS2 directory hierarchy.
639 *
640 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000641static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000642os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
643{
644 APIRET rc;
645 ULONG msglen;
646
647 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
648 Py_BEGIN_ALLOW_THREADS
649 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
650 errorcode, "oso001.msg", &msglen);
651 Py_END_ALLOW_THREADS
652
653 if (rc == NO_ERROR)
654 os2_formatmsg(msgbuf, msglen, reason);
655 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000656 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000657 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000658
659 return msgbuf;
660}
661
662/* Set an OS/2-specific error and return NULL. OS/2 kernel
663 errors are not in a global variable e.g. 'errno' nor are
664 they congruent with posix error numbers. */
665
Victor Stinnerd6f85422010-05-05 23:33:33 +0000666static PyObject *
667os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000668{
669 char text[1024];
670 PyObject *v;
671
672 os2_strerror(text, sizeof(text), code, "");
673
674 v = Py_BuildValue("(is)", code, text);
675 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000676 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000677 Py_DECREF(v);
678 }
679 return NULL; /* Signal to Python that an Exception is Pending */
680}
681
682#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683
684/* POSIX generic methods */
685
Barry Warsaw53699e91996-12-10 23:23:01 +0000686static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000687posix_fildes(PyObject *fdobj, int (*func)(int))
688{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000689 int fd;
690 int res;
691 fd = PyObject_AsFileDescriptor(fdobj);
692 if (fd < 0)
693 return NULL;
694 if (!_PyVerify_fd(fd))
695 return posix_error();
696 Py_BEGIN_ALLOW_THREADS
697 res = (*func)(fd);
698 Py_END_ALLOW_THREADS
699 if (res < 0)
700 return posix_error();
701 Py_INCREF(Py_None);
702 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000703}
Guido van Rossum21142a01999-01-08 21:05:37 +0000704
705static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000706posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000708 char *path1 = NULL;
709 int res;
710 if (!PyArg_ParseTuple(args, format,
711 Py_FileSystemDefaultEncoding, &path1))
712 return NULL;
713 Py_BEGIN_ALLOW_THREADS
714 res = (*func)(path1);
715 Py_END_ALLOW_THREADS
716 if (res < 0)
717 return posix_error_with_allocated_filename(path1);
718 PyMem_Free(path1);
719 Py_INCREF(Py_None);
720 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000721}
722
Barry Warsaw53699e91996-12-10 23:23:01 +0000723static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000724posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000725 char *format,
726 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000727{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000728 char *path1 = NULL, *path2 = NULL;
729 int res;
730 if (!PyArg_ParseTuple(args, format,
731 Py_FileSystemDefaultEncoding, &path1,
732 Py_FileSystemDefaultEncoding, &path2))
733 return NULL;
734 Py_BEGIN_ALLOW_THREADS
735 res = (*func)(path1, path2);
736 Py_END_ALLOW_THREADS
737 PyMem_Free(path1);
738 PyMem_Free(path2);
739 if (res != 0)
740 /* XXX how to report both path1 and path2??? */
741 return posix_error();
742 Py_INCREF(Py_None);
743 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000744}
745
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000746#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000747static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000748win32_1str(PyObject* args, char* func,
749 char* format, BOOL (__stdcall *funcA)(LPCSTR),
750 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000751{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000752 PyObject *uni;
753 char *ansi;
754 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000755
Victor Stinnerd6f85422010-05-05 23:33:33 +0000756 if (!PyArg_ParseTuple(args, wformat, &uni))
757 PyErr_Clear();
758 else {
759 Py_BEGIN_ALLOW_THREADS
760 result = funcW(PyUnicode_AsUnicode(uni));
761 Py_END_ALLOW_THREADS
762 if (!result)
763 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
764 Py_INCREF(Py_None);
765 return Py_None;
766 }
767 if (!PyArg_ParseTuple(args, format, &ansi))
768 return NULL;
769 Py_BEGIN_ALLOW_THREADS
770 result = funcA(ansi);
771 Py_END_ALLOW_THREADS
772 if (!result)
773 return win32_error(func, ansi);
774 Py_INCREF(Py_None);
775 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000776
777}
778
779/* This is a reimplementation of the C library's chdir function,
780 but one that produces Win32 errors instead of DOS error codes.
781 chdir is essentially a wrapper around SetCurrentDirectory; however,
782 it also needs to set "magic" environment variables indicating
783 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000784static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000785win32_chdir(LPCSTR path)
786{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000787 char new_path[MAX_PATH+1];
788 int result;
789 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000790
Victor Stinnerd6f85422010-05-05 23:33:33 +0000791 if(!SetCurrentDirectoryA(path))
792 return FALSE;
793 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
794 if (!result)
795 return FALSE;
796 /* In the ANSI API, there should not be any paths longer
797 than MAX_PATH. */
798 assert(result <= MAX_PATH+1);
799 if (strncmp(new_path, "\\\\", 2) == 0 ||
800 strncmp(new_path, "//", 2) == 0)
801 /* UNC path, nothing to do. */
802 return TRUE;
803 env[1] = new_path[0];
804 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000805}
806
807/* The Unicode version differs from the ANSI version
808 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000809static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000810win32_wchdir(LPCWSTR path)
811{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000812 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
813 int result;
814 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000815
Victor Stinnerd6f85422010-05-05 23:33:33 +0000816 if(!SetCurrentDirectoryW(path))
817 return FALSE;
818 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
819 if (!result)
820 return FALSE;
821 if (result > MAX_PATH+1) {
822 new_path = malloc(result * sizeof(wchar_t));
823 if (!new_path) {
824 SetLastError(ERROR_OUTOFMEMORY);
825 return FALSE;
826 }
827 result = GetCurrentDirectoryW(result, new_path);
828 if (!result) {
829 free(new_path);
830 return FALSE;
831 }
832 }
833 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
834 wcsncmp(new_path, L"//", 2) == 0)
835 /* UNC path, nothing to do. */
836 return TRUE;
837 env[1] = new_path[0];
838 result = SetEnvironmentVariableW(env, new_path);
839 if (new_path != _new_path)
840 free(new_path);
841 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000842}
843#endif
844
Martin v. Löwis14694662006-02-03 12:54:16 +0000845#ifdef MS_WINDOWS
846/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
847 - time stamps are restricted to second resolution
848 - file modification times suffer from forth-and-back conversions between
849 UTC and local time
850 Therefore, we implement our own stat, based on the Win32 API directly.
851*/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000852#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000853
854struct win32_stat{
855 int st_dev;
856 __int64 st_ino;
857 unsigned short st_mode;
858 int st_nlink;
859 int st_uid;
860 int st_gid;
861 int st_rdev;
862 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000863 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000864 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000865 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000866 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000867 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000868 int st_ctime_nsec;
869};
870
871static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
872
873static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000874FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000875{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000876 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
877 /* Cannot simply cast and dereference in_ptr,
878 since it might not be aligned properly */
879 __int64 in;
880 memcpy(&in, in_ptr, sizeof(in));
881 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000882 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000883}
884
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000885static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000886time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000887{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000888 /* XXX endianness */
889 __int64 out;
890 out = time_in + secs_between_epochs;
891 out = out * 10000000 + nsec_in / 100;
892 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000893}
894
Martin v. Löwis14694662006-02-03 12:54:16 +0000895/* Below, we *know* that ugo+r is 0444 */
896#if _S_IREAD != 0400
897#error Unsupported C library
898#endif
899static int
900attributes_to_mode(DWORD attr)
901{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000902 int m = 0;
903 if (attr & FILE_ATTRIBUTE_DIRECTORY)
904 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
905 else
906 m |= _S_IFREG;
907 if (attr & FILE_ATTRIBUTE_READONLY)
908 m |= 0444;
909 else
910 m |= 0666;
911 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000912}
913
914static int
915attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
916{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000917 memset(result, 0, sizeof(*result));
918 result->st_mode = attributes_to_mode(info->dwFileAttributes);
919 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
920 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
921 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
922 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000923
Victor Stinnerd6f85422010-05-05 23:33:33 +0000924 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000925}
926
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000927static BOOL
928attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
929{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000930 HANDLE hFindFile;
931 WIN32_FIND_DATAA FileData;
932 hFindFile = FindFirstFileA(pszFile, &FileData);
933 if (hFindFile == INVALID_HANDLE_VALUE)
934 return FALSE;
935 FindClose(hFindFile);
936 pfad->dwFileAttributes = FileData.dwFileAttributes;
937 pfad->ftCreationTime = FileData.ftCreationTime;
938 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
939 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
940 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
941 pfad->nFileSizeLow = FileData.nFileSizeLow;
942 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000943}
944
945static BOOL
946attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
947{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000948 HANDLE hFindFile;
949 WIN32_FIND_DATAW FileData;
950 hFindFile = FindFirstFileW(pszFile, &FileData);
951 if (hFindFile == INVALID_HANDLE_VALUE)
952 return FALSE;
953 FindClose(hFindFile);
954 pfad->dwFileAttributes = FileData.dwFileAttributes;
955 pfad->ftCreationTime = FileData.ftCreationTime;
956 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
957 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
958 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
959 pfad->nFileSizeLow = FileData.nFileSizeLow;
960 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000961}
962
Victor Stinnerd6f85422010-05-05 23:33:33 +0000963static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000964win32_stat(const char* path, struct win32_stat *result)
965{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000966 WIN32_FILE_ATTRIBUTE_DATA info;
967 int code;
968 char *dot;
969 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
970 if (GetLastError() != ERROR_SHARING_VIOLATION) {
971 /* Protocol violation: we explicitly clear errno, instead of
972 setting it to a POSIX error. Callers should use GetLastError. */
973 errno = 0;
974 return -1;
975 } else {
976 /* Could not get attributes on open file. Fall back to
977 reading the directory. */
978 if (!attributes_from_dir(path, &info)) {
979 /* Very strange. This should not fail now */
980 errno = 0;
981 return -1;
982 }
983 }
984 }
985 code = attribute_data_to_stat(&info, result);
986 if (code != 0)
987 return code;
988 /* Set S_IFEXEC if it is an .exe, .bat, ... */
989 dot = strrchr(path, '.');
990 if (dot) {
991 if (stricmp(dot, ".bat") == 0 ||
992 stricmp(dot, ".cmd") == 0 ||
993 stricmp(dot, ".exe") == 0 ||
994 stricmp(dot, ".com") == 0)
995 result->st_mode |= 0111;
996 }
997 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +0000998}
999
Victor Stinnerd6f85422010-05-05 23:33:33 +00001000static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001001win32_wstat(const wchar_t* path, struct win32_stat *result)
1002{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001003 int code;
1004 const wchar_t *dot;
1005 WIN32_FILE_ATTRIBUTE_DATA info;
1006 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1007 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1008 /* Protocol violation: we explicitly clear errno, instead of
1009 setting it to a POSIX error. Callers should use GetLastError. */
1010 errno = 0;
1011 return -1;
1012 } else {
1013 /* Could not get attributes on open file. Fall back to
1014 reading the directory. */
1015 if (!attributes_from_dir_w(path, &info)) {
1016 /* Very strange. This should not fail now */
1017 errno = 0;
1018 return -1;
1019 }
1020 }
1021 }
1022 code = attribute_data_to_stat(&info, result);
1023 if (code < 0)
1024 return code;
1025 /* Set IFEXEC if it is an .exe, .bat, ... */
1026 dot = wcsrchr(path, '.');
1027 if (dot) {
1028 if (_wcsicmp(dot, L".bat") == 0 ||
1029 _wcsicmp(dot, L".cmd") == 0 ||
1030 _wcsicmp(dot, L".exe") == 0 ||
1031 _wcsicmp(dot, L".com") == 0)
1032 result->st_mode |= 0111;
1033 }
1034 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001035}
1036
1037static int
1038win32_fstat(int file_number, struct win32_stat *result)
1039{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001040 BY_HANDLE_FILE_INFORMATION info;
1041 HANDLE h;
1042 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001043
Victor Stinnerd6f85422010-05-05 23:33:33 +00001044 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001045
Victor Stinnerd6f85422010-05-05 23:33:33 +00001046 /* Protocol violation: we explicitly clear errno, instead of
1047 setting it to a POSIX error. Callers should use GetLastError. */
1048 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001049
Victor Stinnerd6f85422010-05-05 23:33:33 +00001050 if (h == INVALID_HANDLE_VALUE) {
1051 /* This is really a C library error (invalid file handle).
1052 We set the Win32 error to the closes one matching. */
1053 SetLastError(ERROR_INVALID_HANDLE);
1054 return -1;
1055 }
1056 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001057
Victor Stinnerd6f85422010-05-05 23:33:33 +00001058 type = GetFileType(h);
1059 if (type == FILE_TYPE_UNKNOWN) {
1060 DWORD error = GetLastError();
1061 if (error != 0) {
1062 return -1;
1063 }
1064 /* else: valid but unknown file */
1065 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001066
Victor Stinnerd6f85422010-05-05 23:33:33 +00001067 if (type != FILE_TYPE_DISK) {
1068 if (type == FILE_TYPE_CHAR)
1069 result->st_mode = _S_IFCHR;
1070 else if (type == FILE_TYPE_PIPE)
1071 result->st_mode = _S_IFIFO;
1072 return 0;
1073 }
1074
1075 if (!GetFileInformationByHandle(h, &info)) {
1076 return -1;
1077 }
1078
1079 /* similar to stat() */
1080 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1081 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1082 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1083 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1084 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1085 /* specific to fstat() */
1086 result->st_nlink = info.nNumberOfLinks;
1087 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1088 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001089}
1090
1091#endif /* MS_WINDOWS */
1092
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001093PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001094"stat_result: Result from stat or lstat.\n\n\
1095This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001096 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001097or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1098\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001099Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1100or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001101\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001102See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001103
1104static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001105 {"st_mode", "protection bits"},
1106 {"st_ino", "inode"},
1107 {"st_dev", "device"},
1108 {"st_nlink", "number of hard links"},
1109 {"st_uid", "user ID of owner"},
1110 {"st_gid", "group ID of owner"},
1111 {"st_size", "total size, in bytes"},
1112 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1113 {NULL, "integer time of last access"},
1114 {NULL, "integer time of last modification"},
1115 {NULL, "integer time of last change"},
1116 {"st_atime", "time of last access"},
1117 {"st_mtime", "time of last modification"},
1118 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001119#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001120 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001121#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001122#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001123 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001124#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001125#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001126 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001127#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001128#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001129 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001130#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001131#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001132 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001133#endif
1134#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001135 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001136#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001137 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001138};
1139
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001140#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001141#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001142#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001143#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001144#endif
1145
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001146#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001147#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1148#else
1149#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1150#endif
1151
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001152#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001153#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1154#else
1155#define ST_RDEV_IDX ST_BLOCKS_IDX
1156#endif
1157
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001158#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1159#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1160#else
1161#define ST_FLAGS_IDX ST_RDEV_IDX
1162#endif
1163
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001164#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001165#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001166#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001167#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001168#endif
1169
1170#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1171#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1172#else
1173#define ST_BIRTHTIME_IDX ST_GEN_IDX
1174#endif
1175
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001176static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001177 "stat_result", /* name */
1178 stat_result__doc__, /* doc */
1179 stat_result_fields,
1180 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001181};
1182
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001183PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001184"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1185This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001186 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001187or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001188\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001189See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001190
1191static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001192 {"f_bsize", },
1193 {"f_frsize", },
1194 {"f_blocks", },
1195 {"f_bfree", },
1196 {"f_bavail", },
1197 {"f_files", },
1198 {"f_ffree", },
1199 {"f_favail", },
1200 {"f_flag", },
1201 {"f_namemax",},
1202 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001203};
1204
1205static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001206 "statvfs_result", /* name */
1207 statvfs_result__doc__, /* doc */
1208 statvfs_result_fields,
1209 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001210};
1211
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001212static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001213static PyTypeObject StatResultType;
1214static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001215static newfunc structseq_new;
1216
1217static PyObject *
1218statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1219{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001220 PyStructSequence *result;
1221 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001222
Victor Stinnerd6f85422010-05-05 23:33:33 +00001223 result = (PyStructSequence*)structseq_new(type, args, kwds);
1224 if (!result)
1225 return NULL;
1226 /* If we have been initialized from a tuple,
1227 st_?time might be set to None. Initialize it
1228 from the int slots. */
1229 for (i = 7; i <= 9; i++) {
1230 if (result->ob_item[i+3] == Py_None) {
1231 Py_DECREF(Py_None);
1232 Py_INCREF(result->ob_item[i]);
1233 result->ob_item[i+3] = result->ob_item[i];
1234 }
1235 }
1236 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001237}
1238
1239
1240
1241/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001242static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001243
1244PyDoc_STRVAR(stat_float_times__doc__,
1245"stat_float_times([newval]) -> oldval\n\n\
1246Determine whether os.[lf]stat represents time stamps as float objects.\n\
1247If newval is True, future calls to stat() return floats, if it is False,\n\
1248future calls return ints. \n\
1249If newval is omitted, return the current setting.\n");
1250
1251static PyObject*
1252stat_float_times(PyObject* self, PyObject *args)
1253{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001254 int newval = -1;
1255 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1256 return NULL;
1257 if (newval == -1)
1258 /* Return old value */
1259 return PyBool_FromLong(_stat_float_times);
1260 _stat_float_times = newval;
1261 Py_INCREF(Py_None);
1262 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001263}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001264
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001265static void
1266fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1267{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001268 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001269#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001270 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001271#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001272 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001273#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001274 if (!ival)
1275 return;
1276 if (_stat_float_times) {
1277 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1278 } else {
1279 fval = ival;
1280 Py_INCREF(fval);
1281 }
1282 PyStructSequence_SET_ITEM(v, index, ival);
1283 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001284}
1285
Tim Peters5aa91602002-01-30 05:46:57 +00001286/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001287 (used by posix_stat() and posix_fstat()) */
1288static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001289_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001290{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001291 unsigned long ansec, mnsec, cnsec;
1292 PyObject *v = PyStructSequence_New(&StatResultType);
1293 if (v == NULL)
1294 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001295
Victor Stinnerd6f85422010-05-05 23:33:33 +00001296 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001297#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001298 PyStructSequence_SET_ITEM(v, 1,
1299 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001300#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001301 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001302#endif
1303#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001304 PyStructSequence_SET_ITEM(v, 2,
1305 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001306#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001308#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001309 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1310 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1311 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001312#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001313 PyStructSequence_SET_ITEM(v, 6,
1314 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001315#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001316 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001317#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001318
Martin v. Löwis14694662006-02-03 12:54:16 +00001319#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001320 ansec = st->st_atim.tv_nsec;
1321 mnsec = st->st_mtim.tv_nsec;
1322 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001323#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001324 ansec = st->st_atimespec.tv_nsec;
1325 mnsec = st->st_mtimespec.tv_nsec;
1326 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001327#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001328 ansec = st->st_atime_nsec;
1329 mnsec = st->st_mtime_nsec;
1330 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001331#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001332 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001333#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001334 fill_time(v, 7, st->st_atime, ansec);
1335 fill_time(v, 8, st->st_mtime, mnsec);
1336 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001337
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001338#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001339 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1340 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001341#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001342#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001343 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1344 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001345#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001346#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001347 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1348 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001349#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001350#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001351 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1352 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001353#endif
1354#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001355 {
1356 PyObject *val;
1357 unsigned long bsec,bnsec;
1358 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001360 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001361#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001362 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001363#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001364 if (_stat_float_times) {
1365 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1366 } else {
1367 val = PyInt_FromLong((long)bsec);
1368 }
1369 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1370 val);
1371 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001372#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001373#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001374 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1375 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001376#endif
Fred Drake699f3522000-06-29 21:12:41 +00001377
Victor Stinnerd6f85422010-05-05 23:33:33 +00001378 if (PyErr_Occurred()) {
1379 Py_DECREF(v);
1380 return NULL;
1381 }
Fred Drake699f3522000-06-29 21:12:41 +00001382
Victor Stinnerd6f85422010-05-05 23:33:33 +00001383 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001384}
1385
Martin v. Löwisd8948722004-06-02 09:57:56 +00001386#ifdef MS_WINDOWS
1387
1388/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1389 where / can be used in place of \ and the trailing slash is optional.
1390 Both SERVER and SHARE must have at least one character.
1391*/
1392
1393#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1394#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001395#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001396#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001397#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001398
Tim Peters4ad82172004-08-30 17:02:04 +00001399static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001400IsUNCRootA(char *path, int pathlen)
1401{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001402 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001403
Victor Stinnerd6f85422010-05-05 23:33:33 +00001404 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001405
Victor Stinnerd6f85422010-05-05 23:33:33 +00001406 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1407 /* minimum UNCRoot is \\x\y */
1408 return FALSE;
1409 for (i = 2; i < pathlen ; i++)
1410 if (ISSLASH(path[i])) break;
1411 if (i == 2 || i == pathlen)
1412 /* do not allow \\\SHARE or \\SERVER */
1413 return FALSE;
1414 share = i+1;
1415 for (i = share; i < pathlen; i++)
1416 if (ISSLASH(path[i])) break;
1417 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001418
Victor Stinnerd6f85422010-05-05 23:33:33 +00001419 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001420}
1421
Tim Peters4ad82172004-08-30 17:02:04 +00001422static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001423IsUNCRootW(Py_UNICODE *path, int pathlen)
1424{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001425 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001426
Victor Stinnerd6f85422010-05-05 23:33:33 +00001427 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001428
Victor Stinnerd6f85422010-05-05 23:33:33 +00001429 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1430 /* minimum UNCRoot is \\x\y */
1431 return FALSE;
1432 for (i = 2; i < pathlen ; i++)
1433 if (ISSLASH(path[i])) break;
1434 if (i == 2 || i == pathlen)
1435 /* do not allow \\\SHARE or \\SERVER */
1436 return FALSE;
1437 share = i+1;
1438 for (i = share; i < pathlen; i++)
1439 if (ISSLASH(path[i])) break;
1440 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001441
Victor Stinnerd6f85422010-05-05 23:33:33 +00001442 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001443}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001444#endif /* MS_WINDOWS */
1445
Barry Warsaw53699e91996-12-10 23:23:01 +00001446static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001447posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001448 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001449#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001450 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001451#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001452 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001453#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001454 char *wformat,
1455 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001456{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001457 STRUCT_STAT st;
1458 char *path = NULL; /* pass this to stat; do not free() it */
1459 char *pathfree = NULL; /* this memory must be free'd */
1460 int res;
1461 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001462
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001463#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001464 PyUnicodeObject *po;
1465 if (PyArg_ParseTuple(args, wformat, &po)) {
1466 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001467
Victor Stinnerd6f85422010-05-05 23:33:33 +00001468 Py_BEGIN_ALLOW_THREADS
1469 /* PyUnicode_AS_UNICODE result OK without
1470 thread lock as it is a simple dereference. */
1471 res = wstatfunc(wpath, &st);
1472 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001473
Victor Stinnerd6f85422010-05-05 23:33:33 +00001474 if (res != 0)
1475 return win32_error_unicode("stat", wpath);
1476 return _pystat_fromstructstat(&st);
1477 }
1478 /* Drop the argument parsing error as narrow strings
1479 are also valid. */
1480 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001481#endif
1482
Victor Stinnerd6f85422010-05-05 23:33:33 +00001483 if (!PyArg_ParseTuple(args, format,
1484 Py_FileSystemDefaultEncoding, &path))
1485 return NULL;
1486 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001487
Victor Stinnerd6f85422010-05-05 23:33:33 +00001488 Py_BEGIN_ALLOW_THREADS
1489 res = (*statfunc)(path, &st);
1490 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001491
Victor Stinnerd6f85422010-05-05 23:33:33 +00001492 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001493#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001494 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001495#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001496 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001497#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001498 }
1499 else
1500 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001501
Victor Stinnerd6f85422010-05-05 23:33:33 +00001502 PyMem_Free(pathfree);
1503 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001504}
1505
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001506/* POSIX methods */
1507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001508PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001509"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001510Use the real uid/gid to test for access to a path. Note that most\n\
1511operations will use the effective uid/gid, therefore this routine can\n\
1512be used in a suid/sgid environment to test if the invoking user has the\n\
1513specified access to the path. The mode argument can be F_OK to test\n\
1514existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001515
1516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001517posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001518{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001519 char *path;
1520 int mode;
1521
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001522#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001523 DWORD attr;
1524 PyUnicodeObject *po;
1525 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1526 Py_BEGIN_ALLOW_THREADS
1527 /* PyUnicode_AS_UNICODE OK without thread lock as
1528 it is a simple dereference. */
1529 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1530 Py_END_ALLOW_THREADS
1531 goto finish;
1532 }
1533 /* Drop the argument parsing error as narrow strings
1534 are also valid. */
1535 PyErr_Clear();
1536 if (!PyArg_ParseTuple(args, "eti:access",
1537 Py_FileSystemDefaultEncoding, &path, &mode))
1538 return NULL;
1539 Py_BEGIN_ALLOW_THREADS
1540 attr = GetFileAttributesA(path);
1541 Py_END_ALLOW_THREADS
1542 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001543finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001544 if (attr == 0xFFFFFFFF)
1545 /* File does not exist, or cannot read attributes */
1546 return PyBool_FromLong(0);
1547 /* Access is possible if either write access wasn't requested, or
1548 the file isn't read-only, or if it's a directory, as there are
1549 no read-only directories on Windows. */
1550 return PyBool_FromLong(!(mode & 2)
1551 || !(attr & FILE_ATTRIBUTE_READONLY)
1552 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001553#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001554 int res;
1555 if (!PyArg_ParseTuple(args, "eti:access",
1556 Py_FileSystemDefaultEncoding, &path, &mode))
1557 return NULL;
1558 Py_BEGIN_ALLOW_THREADS
1559 res = access(path, mode);
1560 Py_END_ALLOW_THREADS
1561 PyMem_Free(path);
1562 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001563#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001564}
1565
Guido van Rossumd371ff11999-01-25 16:12:23 +00001566#ifndef F_OK
1567#define F_OK 0
1568#endif
1569#ifndef R_OK
1570#define R_OK 4
1571#endif
1572#ifndef W_OK
1573#define W_OK 2
1574#endif
1575#ifndef X_OK
1576#define X_OK 1
1577#endif
1578
1579#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001580PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001581"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001582Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001583
1584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001585posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001586{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001587 int id;
1588 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001589
Victor Stinnerd6f85422010-05-05 23:33:33 +00001590 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1591 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001592
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001593#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001594 /* file descriptor 0 only, the default input device (stdin) */
1595 if (id == 0) {
1596 ret = ttyname();
1597 }
1598 else {
1599 ret = NULL;
1600 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001601#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001602 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001603#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001604 if (ret == NULL)
1605 return posix_error();
1606 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001607}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001608#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001609
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001610#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001611PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001612"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001614
1615static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001616posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001617{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001618 char *ret;
1619 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001620
Greg Wardb48bc172000-03-01 21:51:56 +00001621#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001622 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001623#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001624 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001625#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001626 if (ret == NULL)
1627 return posix_error();
1628 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001629}
1630#endif
1631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001633"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001634Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001635
Barry Warsaw53699e91996-12-10 23:23:01 +00001636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001637posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001638{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001639#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001640 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001641#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001643#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001644 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001645#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001646 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001647#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001648}
1649
Fred Drake4d1e64b2002-04-15 19:40:07 +00001650#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001651PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001652"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001653Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001654opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001655
1656static PyObject *
1657posix_fchdir(PyObject *self, PyObject *fdobj)
1658{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001659 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001660}
1661#endif /* HAVE_FCHDIR */
1662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001663
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001664PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001665"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001666Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001667
Barry Warsaw53699e91996-12-10 23:23:01 +00001668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001669posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001670{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001671 char *path = NULL;
1672 int i;
1673 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001674#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001675 DWORD attr;
1676 PyUnicodeObject *po;
1677 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1678 Py_BEGIN_ALLOW_THREADS
1679 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1680 if (attr != 0xFFFFFFFF) {
1681 if (i & _S_IWRITE)
1682 attr &= ~FILE_ATTRIBUTE_READONLY;
1683 else
1684 attr |= FILE_ATTRIBUTE_READONLY;
1685 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1686 }
1687 else
1688 res = 0;
1689 Py_END_ALLOW_THREADS
1690 if (!res)
1691 return win32_error_unicode("chmod",
1692 PyUnicode_AS_UNICODE(po));
1693 Py_INCREF(Py_None);
1694 return Py_None;
1695 }
1696 /* Drop the argument parsing error as narrow strings
1697 are also valid. */
1698 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001699
Victor Stinnerd6f85422010-05-05 23:33:33 +00001700 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1701 &path, &i))
1702 return NULL;
1703 Py_BEGIN_ALLOW_THREADS
1704 attr = GetFileAttributesA(path);
1705 if (attr != 0xFFFFFFFF) {
1706 if (i & _S_IWRITE)
1707 attr &= ~FILE_ATTRIBUTE_READONLY;
1708 else
1709 attr |= FILE_ATTRIBUTE_READONLY;
1710 res = SetFileAttributesA(path, attr);
1711 }
1712 else
1713 res = 0;
1714 Py_END_ALLOW_THREADS
1715 if (!res) {
1716 win32_error("chmod", path);
1717 PyMem_Free(path);
1718 return NULL;
1719 }
1720 PyMem_Free(path);
1721 Py_INCREF(Py_None);
1722 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001723#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001724 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1725 &path, &i))
1726 return NULL;
1727 Py_BEGIN_ALLOW_THREADS
1728 res = chmod(path, i);
1729 Py_END_ALLOW_THREADS
1730 if (res < 0)
1731 return posix_error_with_allocated_filename(path);
1732 PyMem_Free(path);
1733 Py_INCREF(Py_None);
1734 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001735#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001736}
1737
Christian Heimes36281872007-11-30 21:11:28 +00001738#ifdef HAVE_FCHMOD
1739PyDoc_STRVAR(posix_fchmod__doc__,
1740"fchmod(fd, mode)\n\n\
1741Change the access permissions of the file given by file\n\
1742descriptor fd.");
1743
1744static PyObject *
1745posix_fchmod(PyObject *self, PyObject *args)
1746{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001747 int fd, mode, res;
1748 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1749 return NULL;
1750 Py_BEGIN_ALLOW_THREADS
1751 res = fchmod(fd, mode);
1752 Py_END_ALLOW_THREADS
1753 if (res < 0)
1754 return posix_error();
1755 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001756}
1757#endif /* HAVE_FCHMOD */
1758
1759#ifdef HAVE_LCHMOD
1760PyDoc_STRVAR(posix_lchmod__doc__,
1761"lchmod(path, mode)\n\n\
1762Change the access permissions of a file. If path is a symlink, this\n\
1763affects the link itself rather than the target.");
1764
1765static PyObject *
1766posix_lchmod(PyObject *self, PyObject *args)
1767{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001768 char *path = NULL;
1769 int i;
1770 int res;
1771 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1772 &path, &i))
1773 return NULL;
1774 Py_BEGIN_ALLOW_THREADS
1775 res = lchmod(path, i);
1776 Py_END_ALLOW_THREADS
1777 if (res < 0)
1778 return posix_error_with_allocated_filename(path);
1779 PyMem_Free(path);
1780 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001781}
1782#endif /* HAVE_LCHMOD */
1783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001784
Martin v. Löwis382abef2007-02-19 10:55:19 +00001785#ifdef HAVE_CHFLAGS
1786PyDoc_STRVAR(posix_chflags__doc__,
1787"chflags(path, flags)\n\n\
1788Set file flags.");
1789
1790static PyObject *
1791posix_chflags(PyObject *self, PyObject *args)
1792{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001793 char *path;
1794 unsigned long flags;
1795 int res;
1796 if (!PyArg_ParseTuple(args, "etk:chflags",
1797 Py_FileSystemDefaultEncoding, &path, &flags))
1798 return NULL;
1799 Py_BEGIN_ALLOW_THREADS
1800 res = chflags(path, flags);
1801 Py_END_ALLOW_THREADS
1802 if (res < 0)
1803 return posix_error_with_allocated_filename(path);
1804 PyMem_Free(path);
1805 Py_INCREF(Py_None);
1806 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001807}
1808#endif /* HAVE_CHFLAGS */
1809
1810#ifdef HAVE_LCHFLAGS
1811PyDoc_STRVAR(posix_lchflags__doc__,
1812"lchflags(path, flags)\n\n\
1813Set file flags.\n\
1814This function will not follow symbolic links.");
1815
1816static PyObject *
1817posix_lchflags(PyObject *self, PyObject *args)
1818{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001819 char *path;
1820 unsigned long flags;
1821 int res;
1822 if (!PyArg_ParseTuple(args, "etk:lchflags",
1823 Py_FileSystemDefaultEncoding, &path, &flags))
1824 return NULL;
1825 Py_BEGIN_ALLOW_THREADS
1826 res = lchflags(path, flags);
1827 Py_END_ALLOW_THREADS
1828 if (res < 0)
1829 return posix_error_with_allocated_filename(path);
1830 PyMem_Free(path);
1831 Py_INCREF(Py_None);
1832 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001833}
1834#endif /* HAVE_LCHFLAGS */
1835
Martin v. Löwis244edc82001-10-04 22:44:26 +00001836#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001838"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001840
1841static PyObject *
1842posix_chroot(PyObject *self, PyObject *args)
1843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001844 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001845}
1846#endif
1847
Guido van Rossum21142a01999-01-08 21:05:37 +00001848#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001850"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001851force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001852
1853static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001854posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001855{
Stefan Krah93f7a322010-11-26 17:35:50 +00001856 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001857}
1858#endif /* HAVE_FSYNC */
1859
1860#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001861
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001862#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001863extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1864#endif
1865
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001866PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001867"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001868force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001870
1871static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001872posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001873{
Stefan Krah93f7a322010-11-26 17:35:50 +00001874 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001875}
1876#endif /* HAVE_FDATASYNC */
1877
1878
Fredrik Lundh10723342000-07-10 16:38:09 +00001879#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001880PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001881"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001882Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001883
Barry Warsaw53699e91996-12-10 23:23:01 +00001884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001885posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001886{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001887 char *path = NULL;
1888 long uid, gid;
1889 int res;
1890 if (!PyArg_ParseTuple(args, "etll:chown",
1891 Py_FileSystemDefaultEncoding, &path,
1892 &uid, &gid))
1893 return NULL;
1894 Py_BEGIN_ALLOW_THREADS
1895 res = chown(path, (uid_t) uid, (gid_t) gid);
1896 Py_END_ALLOW_THREADS
1897 if (res < 0)
1898 return posix_error_with_allocated_filename(path);
1899 PyMem_Free(path);
1900 Py_INCREF(Py_None);
1901 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001903#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001904
Christian Heimes36281872007-11-30 21:11:28 +00001905#ifdef HAVE_FCHOWN
1906PyDoc_STRVAR(posix_fchown__doc__,
1907"fchown(fd, uid, gid)\n\n\
1908Change the owner and group id of the file given by file descriptor\n\
1909fd to the numeric uid and gid.");
1910
1911static PyObject *
1912posix_fchown(PyObject *self, PyObject *args)
1913{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001914 int fd;
1915 long uid, gid;
1916 int res;
1917 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
1918 return NULL;
1919 Py_BEGIN_ALLOW_THREADS
1920 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1921 Py_END_ALLOW_THREADS
1922 if (res < 0)
1923 return posix_error();
1924 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001925}
1926#endif /* HAVE_FCHOWN */
1927
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001928#ifdef HAVE_LCHOWN
1929PyDoc_STRVAR(posix_lchown__doc__,
1930"lchown(path, uid, gid)\n\n\
1931Change the owner and group id of path to the numeric uid and gid.\n\
1932This function will not follow symbolic links.");
1933
1934static PyObject *
1935posix_lchown(PyObject *self, PyObject *args)
1936{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001937 char *path = NULL;
1938 long uid, gid;
1939 int res;
1940 if (!PyArg_ParseTuple(args, "etll:lchown",
1941 Py_FileSystemDefaultEncoding, &path,
1942 &uid, &gid))
1943 return NULL;
1944 Py_BEGIN_ALLOW_THREADS
1945 res = lchown(path, (uid_t) uid, (gid_t) gid);
1946 Py_END_ALLOW_THREADS
1947 if (res < 0)
1948 return posix_error_with_allocated_filename(path);
1949 PyMem_Free(path);
1950 Py_INCREF(Py_None);
1951 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001952}
1953#endif /* HAVE_LCHOWN */
1954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955
Guido van Rossum36bc6801995-06-14 22:54:23 +00001956#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001958"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001959Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001960
Stefan Krah182ae642010-07-13 19:17:08 +00001961#if (defined(__sun) && defined(__SVR4)) || defined(__OpenBSD__)
1962/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
1963static PyObject *
1964posix_getcwd(PyObject *self, PyObject *noargs)
1965{
1966 char buf[PATH_MAX+2];
1967 char *res;
1968
1969 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00001970 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00001971 Py_END_ALLOW_THREADS
1972
1973 if (res == NULL)
1974 return posix_error();
1975
1976 return PyString_FromString(buf);
1977}
1978#else
Barry Warsaw53699e91996-12-10 23:23:01 +00001979static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001980posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001981{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001982 int bufsize_incr = 1024;
1983 int bufsize = 0;
1984 char *tmpbuf = NULL;
1985 char *res = NULL;
1986 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001987
Victor Stinnerd6f85422010-05-05 23:33:33 +00001988 Py_BEGIN_ALLOW_THREADS
1989 do {
1990 bufsize = bufsize + bufsize_incr;
1991 tmpbuf = malloc(bufsize);
1992 if (tmpbuf == NULL) {
1993 break;
1994 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001995#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001996 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001997#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001998 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001999#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002000
Victor Stinnerd6f85422010-05-05 23:33:33 +00002001 if (res == NULL) {
2002 free(tmpbuf);
2003 }
2004 } while ((res == NULL) && (errno == ERANGE));
2005 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002006
Victor Stinnerd6f85422010-05-05 23:33:33 +00002007 if (res == NULL)
2008 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002009
Victor Stinnerd6f85422010-05-05 23:33:33 +00002010 dynamic_return = PyString_FromString(tmpbuf);
2011 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002012
Victor Stinnerd6f85422010-05-05 23:33:33 +00002013 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002014}
Stefan Krah182ae642010-07-13 19:17:08 +00002015#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002016
Walter Dörwald3b918c32002-11-21 20:18:46 +00002017#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002018PyDoc_STRVAR(posix_getcwdu__doc__,
2019"getcwdu() -> path\n\n\
2020Return a unicode string representing the current working directory.");
2021
2022static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002023posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002024{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002025 char buf[1026];
2026 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002027
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002028#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002029 DWORD len;
2030 wchar_t wbuf[1026];
2031 wchar_t *wbuf2 = wbuf;
2032 PyObject *resobj;
2033 Py_BEGIN_ALLOW_THREADS
2034 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2035 /* If the buffer is large enough, len does not include the
2036 terminating \0. If the buffer is too small, len includes
2037 the space needed for the terminator. */
2038 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2039 wbuf2 = malloc(len * sizeof(wchar_t));
2040 if (wbuf2)
2041 len = GetCurrentDirectoryW(len, wbuf2);
2042 }
2043 Py_END_ALLOW_THREADS
2044 if (!wbuf2) {
2045 PyErr_NoMemory();
2046 return NULL;
2047 }
2048 if (!len) {
2049 if (wbuf2 != wbuf) free(wbuf2);
2050 return win32_error("getcwdu", NULL);
2051 }
2052 resobj = PyUnicode_FromWideChar(wbuf2, len);
2053 if (wbuf2 != wbuf) free(wbuf2);
2054 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002055#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002056
Victor Stinnerd6f85422010-05-05 23:33:33 +00002057 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002058#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002059 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002060#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002061 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002062#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002063 Py_END_ALLOW_THREADS
2064 if (res == NULL)
2065 return posix_error();
2066 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002067}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002068#endif /* Py_USING_UNICODE */
2069#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002070
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002071
Guido van Rossumb6775db1994-08-01 11:34:53 +00002072#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002074"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Barry Warsaw53699e91996-12-10 23:23:01 +00002077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002078posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002080 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002082#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002086"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087Return a list containing the names of the entries in the directory.\n\
2088\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002089 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090\n\
2091The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002092entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Barry Warsaw53699e91996-12-10 23:23:01 +00002094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002095posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002096{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002097 /* XXX Should redo this putting the (now four) versions of opendir
2098 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002099#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002100
Victor Stinnerd6f85422010-05-05 23:33:33 +00002101 PyObject *d, *v;
2102 HANDLE hFindFile;
2103 BOOL result;
2104 WIN32_FIND_DATA FileData;
2105 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2106 char *bufptr = namebuf;
2107 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002108
Victor Stinnerd6f85422010-05-05 23:33:33 +00002109 PyObject *po;
2110 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2111 WIN32_FIND_DATAW wFileData;
2112 Py_UNICODE *wnamebuf;
2113 /* Overallocate for \\*.*\0 */
2114 len = PyUnicode_GET_SIZE(po);
2115 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2116 if (!wnamebuf) {
2117 PyErr_NoMemory();
2118 return NULL;
2119 }
2120 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2121 if (len > 0) {
2122 Py_UNICODE wch = wnamebuf[len-1];
2123 if (wch != L'/' && wch != L'\\' && wch != L':')
2124 wnamebuf[len++] = L'\\';
2125 wcscpy(wnamebuf + len, L"*.*");
2126 }
2127 if ((d = PyList_New(0)) == NULL) {
2128 free(wnamebuf);
2129 return NULL;
2130 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002131 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002132 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002133 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002134 if (hFindFile == INVALID_HANDLE_VALUE) {
2135 int error = GetLastError();
2136 if (error == ERROR_FILE_NOT_FOUND) {
2137 free(wnamebuf);
2138 return d;
2139 }
2140 Py_DECREF(d);
2141 win32_error_unicode("FindFirstFileW", wnamebuf);
2142 free(wnamebuf);
2143 return NULL;
2144 }
2145 do {
2146 /* Skip over . and .. */
2147 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2148 wcscmp(wFileData.cFileName, L"..") != 0) {
2149 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2150 if (v == NULL) {
2151 Py_DECREF(d);
2152 d = NULL;
2153 break;
2154 }
2155 if (PyList_Append(d, v) != 0) {
2156 Py_DECREF(v);
2157 Py_DECREF(d);
2158 d = NULL;
2159 break;
2160 }
2161 Py_DECREF(v);
2162 }
2163 Py_BEGIN_ALLOW_THREADS
2164 result = FindNextFileW(hFindFile, &wFileData);
2165 Py_END_ALLOW_THREADS
2166 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2167 it got to the end of the directory. */
2168 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2169 Py_DECREF(d);
2170 win32_error_unicode("FindNextFileW", wnamebuf);
2171 FindClose(hFindFile);
2172 free(wnamebuf);
2173 return NULL;
2174 }
2175 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002176
Victor Stinnerd6f85422010-05-05 23:33:33 +00002177 if (FindClose(hFindFile) == FALSE) {
2178 Py_DECREF(d);
2179 win32_error_unicode("FindClose", wnamebuf);
2180 free(wnamebuf);
2181 return NULL;
2182 }
2183 free(wnamebuf);
2184 return d;
2185 }
2186 /* Drop the argument parsing error as narrow strings
2187 are also valid. */
2188 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002189
Victor Stinnerd6f85422010-05-05 23:33:33 +00002190 if (!PyArg_ParseTuple(args, "et#:listdir",
2191 Py_FileSystemDefaultEncoding, &bufptr, &len))
2192 return NULL;
2193 if (len > 0) {
2194 char ch = namebuf[len-1];
2195 if (ch != SEP && ch != ALTSEP && ch != ':')
2196 namebuf[len++] = '/';
2197 strcpy(namebuf + len, "*.*");
2198 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002199
Victor Stinnerd6f85422010-05-05 23:33:33 +00002200 if ((d = PyList_New(0)) == NULL)
2201 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002202
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002203 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002205 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002206 if (hFindFile == INVALID_HANDLE_VALUE) {
2207 int error = GetLastError();
2208 if (error == ERROR_FILE_NOT_FOUND)
2209 return d;
2210 Py_DECREF(d);
2211 return win32_error("FindFirstFile", namebuf);
2212 }
2213 do {
2214 /* Skip over . and .. */
2215 if (strcmp(FileData.cFileName, ".") != 0 &&
2216 strcmp(FileData.cFileName, "..") != 0) {
2217 v = PyString_FromString(FileData.cFileName);
2218 if (v == NULL) {
2219 Py_DECREF(d);
2220 d = NULL;
2221 break;
2222 }
2223 if (PyList_Append(d, v) != 0) {
2224 Py_DECREF(v);
2225 Py_DECREF(d);
2226 d = NULL;
2227 break;
2228 }
2229 Py_DECREF(v);
2230 }
2231 Py_BEGIN_ALLOW_THREADS
2232 result = FindNextFile(hFindFile, &FileData);
2233 Py_END_ALLOW_THREADS
2234 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2235 it got to the end of the directory. */
2236 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2237 Py_DECREF(d);
2238 win32_error("FindNextFile", namebuf);
2239 FindClose(hFindFile);
2240 return NULL;
2241 }
2242 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002243
Victor Stinnerd6f85422010-05-05 23:33:33 +00002244 if (FindClose(hFindFile) == FALSE) {
2245 Py_DECREF(d);
2246 return win32_error("FindClose", namebuf);
2247 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002248
Victor Stinnerd6f85422010-05-05 23:33:33 +00002249 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002250
Tim Peters0bb44a42000-09-15 07:44:49 +00002251#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252
2253#ifndef MAX_PATH
2254#define MAX_PATH CCHMAXPATH
2255#endif
2256 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002257 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258 PyObject *d, *v;
2259 char namebuf[MAX_PATH+5];
2260 HDIR hdir = 1;
2261 ULONG srchcnt = 1;
2262 FILEFINDBUF3 ep;
2263 APIRET rc;
2264
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002265 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002266 return NULL;
2267 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002268 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002269 return NULL;
2270 }
2271 strcpy(namebuf, name);
2272 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002273 if (*pt == ALTSEP)
2274 *pt = SEP;
2275 if (namebuf[len-1] != SEP)
2276 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277 strcpy(namebuf + len, "*.*");
2278
Victor Stinnerd6f85422010-05-05 23:33:33 +00002279 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002280 return NULL;
2281
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002282 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2283 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002285 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2286 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2287 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
2289 if (rc != NO_ERROR) {
2290 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002291 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292 }
2293
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002294 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295 do {
2296 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002297 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002298 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299
2300 strcpy(namebuf, ep.achName);
2301
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002302 /* Leave Case of Name Alone -- In Native Form */
2303 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002305 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306 if (v == NULL) {
2307 Py_DECREF(d);
2308 d = NULL;
2309 break;
2310 }
2311 if (PyList_Append(d, v) != 0) {
2312 Py_DECREF(v);
2313 Py_DECREF(d);
2314 d = NULL;
2315 break;
2316 }
2317 Py_DECREF(v);
2318 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2319 }
2320
2321 return d;
2322#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002323
Victor Stinnerd6f85422010-05-05 23:33:33 +00002324 char *name = NULL;
2325 PyObject *d, *v;
2326 DIR *dirp;
2327 struct dirent *ep;
2328 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002329
Victor Stinnerd6f85422010-05-05 23:33:33 +00002330 errno = 0;
2331 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2332 arg_is_unicode = 0;
2333 PyErr_Clear();
2334 }
2335 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2336 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002337 Py_BEGIN_ALLOW_THREADS
2338 dirp = opendir(name);
2339 Py_END_ALLOW_THREADS
2340 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002341 return posix_error_with_allocated_filename(name);
2342 }
2343 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002344 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002345 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002346 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002347 PyMem_Free(name);
2348 return NULL;
2349 }
2350 for (;;) {
2351 errno = 0;
2352 Py_BEGIN_ALLOW_THREADS
2353 ep = readdir(dirp);
2354 Py_END_ALLOW_THREADS
2355 if (ep == NULL) {
2356 if (errno == 0) {
2357 break;
2358 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002359 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002360 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002361 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002362 Py_DECREF(d);
2363 return posix_error_with_allocated_filename(name);
2364 }
2365 }
2366 if (ep->d_name[0] == '.' &&
2367 (NAMLEN(ep) == 1 ||
2368 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2369 continue;
2370 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2371 if (v == NULL) {
2372 Py_DECREF(d);
2373 d = NULL;
2374 break;
2375 }
Just van Rossum46c97842003-02-25 21:42:15 +00002376#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002377 if (arg_is_unicode) {
2378 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002379
Victor Stinnerd6f85422010-05-05 23:33:33 +00002380 w = PyUnicode_FromEncodedObject(v,
2381 Py_FileSystemDefaultEncoding,
2382 "strict");
2383 if (w != NULL) {
2384 Py_DECREF(v);
2385 v = w;
2386 }
2387 else {
2388 /* fall back to the original byte string, as
2389 discussed in patch #683592 */
2390 PyErr_Clear();
2391 }
2392 }
Just van Rossum46c97842003-02-25 21:42:15 +00002393#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002394 if (PyList_Append(d, v) != 0) {
2395 Py_DECREF(v);
2396 Py_DECREF(d);
2397 d = NULL;
2398 break;
2399 }
2400 Py_DECREF(v);
2401 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002402 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002403 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002404 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002405 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002406
Victor Stinnerd6f85422010-05-05 23:33:33 +00002407 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002408
Tim Peters0bb44a42000-09-15 07:44:49 +00002409#endif /* which OS */
2410} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002411
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002412#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002413/* A helper function for abspath on win32 */
2414static PyObject *
2415posix__getfullpathname(PyObject *self, PyObject *args)
2416{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002417 /* assume encoded strings won't more than double no of chars */
2418 char inbuf[MAX_PATH*2];
2419 char *inbufp = inbuf;
2420 Py_ssize_t insize = sizeof(inbuf);
2421 char outbuf[MAX_PATH*2];
2422 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002423
Victor Stinnerd6f85422010-05-05 23:33:33 +00002424 PyUnicodeObject *po;
2425 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2426 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2427 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2428 Py_UNICODE *wtemp;
2429 DWORD result;
2430 PyObject *v;
2431 result = GetFullPathNameW(wpath,
2432 sizeof(woutbuf)/sizeof(woutbuf[0]),
2433 woutbuf, &wtemp);
2434 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2435 woutbufp = malloc(result * sizeof(Py_UNICODE));
2436 if (!woutbufp)
2437 return PyErr_NoMemory();
2438 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2439 }
2440 if (result)
2441 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2442 else
2443 v = win32_error_unicode("GetFullPathNameW", wpath);
2444 if (woutbufp != woutbuf)
2445 free(woutbufp);
2446 return v;
2447 }
2448 /* Drop the argument parsing error as narrow strings
2449 are also valid. */
2450 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002451
Victor Stinnerd6f85422010-05-05 23:33:33 +00002452 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2453 Py_FileSystemDefaultEncoding, &inbufp,
2454 &insize))
2455 return NULL;
2456 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2457 outbuf, &temp))
2458 return win32_error("GetFullPathName", inbuf);
2459 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2460 return PyUnicode_Decode(outbuf, strlen(outbuf),
2461 Py_FileSystemDefaultEncoding, NULL);
2462 }
2463 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002464} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002465#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002467PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002468"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002469Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002470
Barry Warsaw53699e91996-12-10 23:23:01 +00002471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002472posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002473{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002474 int res;
2475 char *path = NULL;
2476 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002477
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002478#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002479 PyUnicodeObject *po;
2480 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2481 Py_BEGIN_ALLOW_THREADS
2482 /* PyUnicode_AS_UNICODE OK without thread lock as
2483 it is a simple dereference. */
2484 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2485 Py_END_ALLOW_THREADS
2486 if (!res)
2487 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2488 Py_INCREF(Py_None);
2489 return Py_None;
2490 }
2491 /* Drop the argument parsing error as narrow strings
2492 are also valid. */
2493 PyErr_Clear();
2494 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2495 Py_FileSystemDefaultEncoding, &path, &mode))
2496 return NULL;
2497 Py_BEGIN_ALLOW_THREADS
2498 /* PyUnicode_AS_UNICODE OK without thread lock as
2499 it is a simple dereference. */
2500 res = CreateDirectoryA(path, NULL);
2501 Py_END_ALLOW_THREADS
2502 if (!res) {
2503 win32_error("mkdir", path);
2504 PyMem_Free(path);
2505 return NULL;
2506 }
2507 PyMem_Free(path);
2508 Py_INCREF(Py_None);
2509 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002510#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002511
Victor Stinnerd6f85422010-05-05 23:33:33 +00002512 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2513 Py_FileSystemDefaultEncoding, &path, &mode))
2514 return NULL;
2515 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002516#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002518#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002519 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002520#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002521 Py_END_ALLOW_THREADS
2522 if (res < 0)
2523 return posix_error_with_allocated_filename(path);
2524 PyMem_Free(path);
2525 Py_INCREF(Py_None);
2526 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002527#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002528}
2529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002530
Neal Norwitz1818ed72006-03-26 00:29:48 +00002531/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2532#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002533#include <sys/resource.h>
2534#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002535
Neal Norwitz1818ed72006-03-26 00:29:48 +00002536
2537#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002539"nice(inc) -> new_priority\n\n\
2540Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002541
Barry Warsaw53699e91996-12-10 23:23:01 +00002542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002543posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002544{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002545 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002546
Victor Stinnerd6f85422010-05-05 23:33:33 +00002547 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2548 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002549
Victor Stinnerd6f85422010-05-05 23:33:33 +00002550 /* There are two flavours of 'nice': one that returns the new
2551 priority (as required by almost all standards out there) and the
2552 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2553 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002554
Victor Stinnerd6f85422010-05-05 23:33:33 +00002555 If we are of the nice family that returns the new priority, we
2556 need to clear errno before the call, and check if errno is filled
2557 before calling posix_error() on a returnvalue of -1, because the
2558 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002559
Victor Stinnerd6f85422010-05-05 23:33:33 +00002560 errno = 0;
2561 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002562#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002563 if (value == 0)
2564 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002565#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002566 if (value == -1 && errno != 0)
2567 /* either nice() or getpriority() returned an error */
2568 return posix_error();
2569 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002570}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002571#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002573PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002574"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002575Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002576
Barry Warsaw53699e91996-12-10 23:23:01 +00002577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002578posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002579{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002580#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002581 PyObject *o1, *o2;
2582 char *p1, *p2;
2583 BOOL result;
2584 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2585 goto error;
2586 if (!convert_to_unicode(&o1))
2587 goto error;
2588 if (!convert_to_unicode(&o2)) {
2589 Py_DECREF(o1);
2590 goto error;
2591 }
2592 Py_BEGIN_ALLOW_THREADS
2593 result = MoveFileW(PyUnicode_AsUnicode(o1),
2594 PyUnicode_AsUnicode(o2));
2595 Py_END_ALLOW_THREADS
2596 Py_DECREF(o1);
2597 Py_DECREF(o2);
2598 if (!result)
2599 return win32_error("rename", NULL);
2600 Py_INCREF(Py_None);
2601 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002602error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002603 PyErr_Clear();
2604 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2605 return NULL;
2606 Py_BEGIN_ALLOW_THREADS
2607 result = MoveFileA(p1, p2);
2608 Py_END_ALLOW_THREADS
2609 if (!result)
2610 return win32_error("rename", NULL);
2611 Py_INCREF(Py_None);
2612 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002613#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002614 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002615#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002616}
2617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002619PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002620"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002621Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002622
Barry Warsaw53699e91996-12-10 23:23:01 +00002623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002624posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002625{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002627 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002628#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002629 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002630#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002631}
2632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002635"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002637
Barry Warsaw53699e91996-12-10 23:23:01 +00002638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002639posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002640{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002642 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002643#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002644 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002645#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002646}
2647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002648
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002649#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002651"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002652Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002653
Barry Warsaw53699e91996-12-10 23:23:01 +00002654static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002655posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002656{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002657 char *command;
2658 long sts;
2659 if (!PyArg_ParseTuple(args, "s:system", &command))
2660 return NULL;
2661 Py_BEGIN_ALLOW_THREADS
2662 sts = system(command);
2663 Py_END_ALLOW_THREADS
2664 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002666#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002670"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002671Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002672
Barry Warsaw53699e91996-12-10 23:23:01 +00002673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002674posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002675{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002676 int i;
2677 if (!PyArg_ParseTuple(args, "i:umask", &i))
2678 return NULL;
2679 i = (int)umask(i);
2680 if (i < 0)
2681 return posix_error();
2682 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002683}
2684
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002685
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002687"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002688Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002689
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002690PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002691"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002692Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002693
Barry Warsaw53699e91996-12-10 23:23:01 +00002694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002695posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002696{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002698 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002699#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002700 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002701#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002702}
2703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002704
Guido van Rossumb6775db1994-08-01 11:34:53 +00002705#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002707"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002708Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002709
Barry Warsaw53699e91996-12-10 23:23:01 +00002710static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002711posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002712{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002713 struct utsname u;
2714 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002715
Victor Stinnerd6f85422010-05-05 23:33:33 +00002716 Py_BEGIN_ALLOW_THREADS
2717 res = uname(&u);
2718 Py_END_ALLOW_THREADS
2719 if (res < 0)
2720 return posix_error();
2721 return Py_BuildValue("(sssss)",
2722 u.sysname,
2723 u.nodename,
2724 u.release,
2725 u.version,
2726 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002727}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002728#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002729
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002730static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002731extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002732{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002733 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002734 if (PyFloat_Check(t)) {
2735 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002736 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002737 if (!intobj)
2738 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002739#if SIZEOF_TIME_T > SIZEOF_LONG
2740 intval = PyInt_AsUnsignedLongLongMask(intobj);
2741#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002743#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002744 Py_DECREF(intobj);
2745 if (intval == -1 && PyErr_Occurred())
2746 return -1;
2747 *sec = intval;
2748 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2749 if (*usec < 0)
2750 /* If rounding gave us a negative number,
2751 truncate. */
2752 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002753 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002754 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002755#if SIZEOF_TIME_T > SIZEOF_LONG
2756 intval = PyInt_AsUnsignedLongLongMask(t);
2757#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002758 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002759#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002760 if (intval == -1 && PyErr_Occurred())
2761 return -1;
2762 *sec = intval;
2763 *usec = 0;
2764 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002765}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002767PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002768"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002769utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002770Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002771second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002772
Barry Warsaw53699e91996-12-10 23:23:01 +00002773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002774posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002775{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002776#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002777 PyObject *arg;
2778 PyUnicodeObject *obwpath;
2779 wchar_t *wpath = NULL;
2780 char *apath = NULL;
2781 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002782 time_t atimesec, mtimesec;
2783 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002784 FILETIME atime, mtime;
2785 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002786
Victor Stinnerd6f85422010-05-05 23:33:33 +00002787 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2788 wpath = PyUnicode_AS_UNICODE(obwpath);
2789 Py_BEGIN_ALLOW_THREADS
2790 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2791 NULL, OPEN_EXISTING,
2792 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2793 Py_END_ALLOW_THREADS
2794 if (hFile == INVALID_HANDLE_VALUE)
2795 return win32_error_unicode("utime", wpath);
2796 } else
2797 /* Drop the argument parsing error as narrow strings
2798 are also valid. */
2799 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002800
Victor Stinnerd6f85422010-05-05 23:33:33 +00002801 if (!wpath) {
2802 if (!PyArg_ParseTuple(args, "etO:utime",
2803 Py_FileSystemDefaultEncoding, &apath, &arg))
2804 return NULL;
2805 Py_BEGIN_ALLOW_THREADS
2806 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2807 NULL, OPEN_EXISTING,
2808 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2809 Py_END_ALLOW_THREADS
2810 if (hFile == INVALID_HANDLE_VALUE) {
2811 win32_error("utime", apath);
2812 PyMem_Free(apath);
2813 return NULL;
2814 }
2815 PyMem_Free(apath);
2816 }
2817
2818 if (arg == Py_None) {
2819 SYSTEMTIME now;
2820 GetSystemTime(&now);
2821 if (!SystemTimeToFileTime(&now, &mtime) ||
2822 !SystemTimeToFileTime(&now, &atime)) {
2823 win32_error("utime", NULL);
2824 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00002825 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00002826 }
2827 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2828 PyErr_SetString(PyExc_TypeError,
2829 "utime() arg 2 must be a tuple (atime, mtime)");
2830 goto done;
2831 }
2832 else {
2833 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2834 &atimesec, &ausec) == -1)
2835 goto done;
2836 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2837 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2838 &mtimesec, &musec) == -1)
2839 goto done;
2840 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2841 }
2842 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2843 /* Avoid putting the file name into the error here,
2844 as that may confuse the user into believing that
2845 something is wrong with the file, when it also
2846 could be the time stamp that gives a problem. */
2847 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00002848 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002849 }
2850 Py_INCREF(Py_None);
2851 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002852done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002853 CloseHandle(hFile);
2854 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002855#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002856
Victor Stinnerd6f85422010-05-05 23:33:33 +00002857 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002858 time_t atime, mtime;
2859 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002860 int res;
2861 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002862
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002863#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002864 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002865#define ATIME buf[0].tv_sec
2866#define MTIME buf[1].tv_sec
2867#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002868/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002869 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002870#define ATIME buf.actime
2871#define MTIME buf.modtime
2872#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002873#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002874 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002875#define ATIME buf[0]
2876#define MTIME buf[1]
2877#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002878#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002879
Mark Hammond817c9292003-12-03 01:22:38 +00002880
Victor Stinnerd6f85422010-05-05 23:33:33 +00002881 if (!PyArg_ParseTuple(args, "etO:utime",
2882 Py_FileSystemDefaultEncoding, &path, &arg))
2883 return NULL;
2884 if (arg == Py_None) {
2885 /* optional time values not given */
2886 Py_BEGIN_ALLOW_THREADS
2887 res = utime(path, NULL);
2888 Py_END_ALLOW_THREADS
2889 }
2890 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2891 PyErr_SetString(PyExc_TypeError,
2892 "utime() arg 2 must be a tuple (atime, mtime)");
2893 PyMem_Free(path);
2894 return NULL;
2895 }
2896 else {
2897 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2898 &atime, &ausec) == -1) {
2899 PyMem_Free(path);
2900 return NULL;
2901 }
2902 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2903 &mtime, &musec) == -1) {
2904 PyMem_Free(path);
2905 return NULL;
2906 }
2907 ATIME = atime;
2908 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002909#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002910 buf[0].tv_usec = ausec;
2911 buf[1].tv_usec = musec;
2912 Py_BEGIN_ALLOW_THREADS
2913 res = utimes(path, buf);
2914 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002915#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002916 Py_BEGIN_ALLOW_THREADS
2917 res = utime(path, UTIME_ARG);
2918 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002919#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002920 }
2921 if (res < 0) {
2922 return posix_error_with_allocated_filename(path);
2923 }
2924 PyMem_Free(path);
2925 Py_INCREF(Py_None);
2926 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002927#undef UTIME_ARG
2928#undef ATIME
2929#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002930#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002931}
2932
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933
Guido van Rossum3b066191991-06-04 19:40:25 +00002934/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002935
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002937"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002938Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939
Barry Warsaw53699e91996-12-10 23:23:01 +00002940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002941posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002942{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002943 int sts;
2944 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2945 return NULL;
2946 _exit(sts);
2947 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002948}
2949
Martin v. Löwis114619e2002-10-07 06:44:21 +00002950#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2951static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002952free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002953{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002954 Py_ssize_t i;
2955 for (i = 0; i < count; i++)
2956 PyMem_Free(array[i]);
2957 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002958}
2959#endif
2960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002961
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002962#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002964"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002965Execute an executable path with arguments, replacing current process.\n\
2966\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002967 path: path of executable file\n\
2968 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002969
Barry Warsaw53699e91996-12-10 23:23:01 +00002970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002971posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002973 char *path;
2974 PyObject *argv;
2975 char **argvlist;
2976 Py_ssize_t i, argc;
2977 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002978
Victor Stinnerd6f85422010-05-05 23:33:33 +00002979 /* execv has two arguments: (path, argv), where
2980 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002981
Victor Stinnerd6f85422010-05-05 23:33:33 +00002982 if (!PyArg_ParseTuple(args, "etO:execv",
2983 Py_FileSystemDefaultEncoding,
2984 &path, &argv))
2985 return NULL;
2986 if (PyList_Check(argv)) {
2987 argc = PyList_Size(argv);
2988 getitem = PyList_GetItem;
2989 }
2990 else if (PyTuple_Check(argv)) {
2991 argc = PyTuple_Size(argv);
2992 getitem = PyTuple_GetItem;
2993 }
2994 else {
2995 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2996 PyMem_Free(path);
2997 return NULL;
2998 }
2999 if (argc < 1) {
3000 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
3001 PyMem_Free(path);
3002 return NULL;
3003 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003004
Victor Stinnerd6f85422010-05-05 23:33:33 +00003005 argvlist = PyMem_NEW(char *, argc+1);
3006 if (argvlist == NULL) {
3007 PyMem_Free(path);
3008 return PyErr_NoMemory();
3009 }
3010 for (i = 0; i < argc; i++) {
3011 if (!PyArg_Parse((*getitem)(argv, i), "et",
3012 Py_FileSystemDefaultEncoding,
3013 &argvlist[i])) {
3014 free_string_array(argvlist, i);
3015 PyErr_SetString(PyExc_TypeError,
3016 "execv() arg 2 must contain only strings");
3017 PyMem_Free(path);
3018 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003019
Victor Stinnerd6f85422010-05-05 23:33:33 +00003020 }
3021 }
3022 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003023
Victor Stinnerd6f85422010-05-05 23:33:33 +00003024 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003025
Victor Stinnerd6f85422010-05-05 23:33:33 +00003026 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003027
Victor Stinnerd6f85422010-05-05 23:33:33 +00003028 free_string_array(argvlist, argc);
3029 PyMem_Free(path);
3030 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003031}
3032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003034PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003035"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003036Execute a path with arguments and environment, replacing current process.\n\
3037\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003038 path: path of executable file\n\
3039 args: tuple or list of arguments\n\
3040 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Barry Warsaw53699e91996-12-10 23:23:01 +00003042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003043posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003044{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003045 char *path;
3046 PyObject *argv, *env;
3047 char **argvlist;
3048 char **envlist;
3049 PyObject *key, *val, *keys=NULL, *vals=NULL;
3050 Py_ssize_t i, pos, argc, envc;
3051 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3052 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003053
Victor Stinnerd6f85422010-05-05 23:33:33 +00003054 /* execve has three arguments: (path, argv, env), where
3055 argv is a list or tuple of strings and env is a dictionary
3056 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003057
Victor Stinnerd6f85422010-05-05 23:33:33 +00003058 if (!PyArg_ParseTuple(args, "etOO:execve",
3059 Py_FileSystemDefaultEncoding,
3060 &path, &argv, &env))
3061 return NULL;
3062 if (PyList_Check(argv)) {
3063 argc = PyList_Size(argv);
3064 getitem = PyList_GetItem;
3065 }
3066 else if (PyTuple_Check(argv)) {
3067 argc = PyTuple_Size(argv);
3068 getitem = PyTuple_GetItem;
3069 }
3070 else {
3071 PyErr_SetString(PyExc_TypeError,
3072 "execve() arg 2 must be a tuple or list");
3073 goto fail_0;
3074 }
3075 if (!PyMapping_Check(env)) {
3076 PyErr_SetString(PyExc_TypeError,
3077 "execve() arg 3 must be a mapping object");
3078 goto fail_0;
3079 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003080
Victor Stinnerd6f85422010-05-05 23:33:33 +00003081 argvlist = PyMem_NEW(char *, argc+1);
3082 if (argvlist == NULL) {
3083 PyErr_NoMemory();
3084 goto fail_0;
3085 }
3086 for (i = 0; i < argc; i++) {
3087 if (!PyArg_Parse((*getitem)(argv, i),
3088 "et;execve() arg 2 must contain only strings",
3089 Py_FileSystemDefaultEncoding,
3090 &argvlist[i]))
3091 {
3092 lastarg = i;
3093 goto fail_1;
3094 }
3095 }
3096 lastarg = argc;
3097 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003098
Victor Stinnerd6f85422010-05-05 23:33:33 +00003099 i = PyMapping_Size(env);
3100 if (i < 0)
3101 goto fail_1;
3102 envlist = PyMem_NEW(char *, i + 1);
3103 if (envlist == NULL) {
3104 PyErr_NoMemory();
3105 goto fail_1;
3106 }
3107 envc = 0;
3108 keys = PyMapping_Keys(env);
3109 vals = PyMapping_Values(env);
3110 if (!keys || !vals)
3111 goto fail_2;
3112 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3113 PyErr_SetString(PyExc_TypeError,
3114 "execve(): env.keys() or env.values() is not a list");
3115 goto fail_2;
3116 }
Tim Peters5aa91602002-01-30 05:46:57 +00003117
Victor Stinnerd6f85422010-05-05 23:33:33 +00003118 for (pos = 0; pos < i; pos++) {
3119 char *p, *k, *v;
3120 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003121
Victor Stinnerd6f85422010-05-05 23:33:33 +00003122 key = PyList_GetItem(keys, pos);
3123 val = PyList_GetItem(vals, pos);
3124 if (!key || !val)
3125 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003126
Victor Stinnerd6f85422010-05-05 23:33:33 +00003127 if (!PyArg_Parse(
3128 key,
3129 "s;execve() arg 3 contains a non-string key",
3130 &k) ||
3131 !PyArg_Parse(
3132 val,
3133 "s;execve() arg 3 contains a non-string value",
3134 &v))
3135 {
3136 goto fail_2;
3137 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003138
3139#if defined(PYOS_OS2)
3140 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3141 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3142#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003143 len = PyString_Size(key) + PyString_Size(val) + 2;
3144 p = PyMem_NEW(char, len);
3145 if (p == NULL) {
3146 PyErr_NoMemory();
3147 goto fail_2;
3148 }
3149 PyOS_snprintf(p, len, "%s=%s", k, v);
3150 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003152 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003153#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003154 }
3155 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003156
Victor Stinnerd6f85422010-05-05 23:33:33 +00003157 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003158
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160
Victor Stinnerd6f85422010-05-05 23:33:33 +00003161 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003162
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003163 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003164 while (--envc >= 0)
3165 PyMem_DEL(envlist[envc]);
3166 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003167 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003168 free_string_array(argvlist, lastarg);
3169 Py_XDECREF(vals);
3170 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003171 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003172 PyMem_Free(path);
3173 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003174}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003175#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177
Guido van Rossuma1065681999-01-25 23:20:23 +00003178#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003180"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003181Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003182\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003183 mode: mode of process creation\n\
3184 path: path of executable file\n\
3185 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003186
3187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003188posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003189{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003190 char *path;
3191 PyObject *argv;
3192 char **argvlist;
3193 int mode, i;
3194 Py_ssize_t argc;
3195 Py_intptr_t spawnval;
3196 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003197
Victor Stinnerd6f85422010-05-05 23:33:33 +00003198 /* spawnv has three arguments: (mode, path, argv), where
3199 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003200
Victor Stinnerd6f85422010-05-05 23:33:33 +00003201 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3202 Py_FileSystemDefaultEncoding,
3203 &path, &argv))
3204 return NULL;
3205 if (PyList_Check(argv)) {
3206 argc = PyList_Size(argv);
3207 getitem = PyList_GetItem;
3208 }
3209 else if (PyTuple_Check(argv)) {
3210 argc = PyTuple_Size(argv);
3211 getitem = PyTuple_GetItem;
3212 }
3213 else {
3214 PyErr_SetString(PyExc_TypeError,
3215 "spawnv() arg 2 must be a tuple or list");
3216 PyMem_Free(path);
3217 return NULL;
3218 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003219
Victor Stinnerd6f85422010-05-05 23:33:33 +00003220 argvlist = PyMem_NEW(char *, argc+1);
3221 if (argvlist == NULL) {
3222 PyMem_Free(path);
3223 return PyErr_NoMemory();
3224 }
3225 for (i = 0; i < argc; i++) {
3226 if (!PyArg_Parse((*getitem)(argv, i), "et",
3227 Py_FileSystemDefaultEncoding,
3228 &argvlist[i])) {
3229 free_string_array(argvlist, i);
3230 PyErr_SetString(
3231 PyExc_TypeError,
3232 "spawnv() arg 2 must contain only strings");
3233 PyMem_Free(path);
3234 return NULL;
3235 }
3236 }
3237 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003238
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003239#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003240 Py_BEGIN_ALLOW_THREADS
3241 spawnval = spawnv(mode, path, argvlist);
3242 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003243#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003244 if (mode == _OLD_P_OVERLAY)
3245 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003246
Victor Stinnerd6f85422010-05-05 23:33:33 +00003247 Py_BEGIN_ALLOW_THREADS
3248 spawnval = _spawnv(mode, path, argvlist);
3249 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003250#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003251
Victor Stinnerd6f85422010-05-05 23:33:33 +00003252 free_string_array(argvlist, argc);
3253 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003254
Victor Stinnerd6f85422010-05-05 23:33:33 +00003255 if (spawnval == -1)
3256 return posix_error();
3257 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003258#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003259 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003260#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003261 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003262#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003263}
3264
3265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003266PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003267"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003268Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003269\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003270 mode: mode of process creation\n\
3271 path: path of executable file\n\
3272 args: tuple or list of arguments\n\
3273 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003274
3275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003276posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003278 char *path;
3279 PyObject *argv, *env;
3280 char **argvlist;
3281 char **envlist;
3282 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3283 int mode, pos, envc;
3284 Py_ssize_t argc, i;
3285 Py_intptr_t spawnval;
3286 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3287 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003288
Victor Stinnerd6f85422010-05-05 23:33:33 +00003289 /* spawnve has four arguments: (mode, path, argv, env), where
3290 argv is a list or tuple of strings and env is a dictionary
3291 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003292
Victor Stinnerd6f85422010-05-05 23:33:33 +00003293 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3294 Py_FileSystemDefaultEncoding,
3295 &path, &argv, &env))
3296 return NULL;
3297 if (PyList_Check(argv)) {
3298 argc = PyList_Size(argv);
3299 getitem = PyList_GetItem;
3300 }
3301 else if (PyTuple_Check(argv)) {
3302 argc = PyTuple_Size(argv);
3303 getitem = PyTuple_GetItem;
3304 }
3305 else {
3306 PyErr_SetString(PyExc_TypeError,
3307 "spawnve() arg 2 must be a tuple or list");
3308 goto fail_0;
3309 }
3310 if (!PyMapping_Check(env)) {
3311 PyErr_SetString(PyExc_TypeError,
3312 "spawnve() arg 3 must be a mapping object");
3313 goto fail_0;
3314 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003315
Victor Stinnerd6f85422010-05-05 23:33:33 +00003316 argvlist = PyMem_NEW(char *, argc+1);
3317 if (argvlist == NULL) {
3318 PyErr_NoMemory();
3319 goto fail_0;
3320 }
3321 for (i = 0; i < argc; i++) {
3322 if (!PyArg_Parse((*getitem)(argv, i),
3323 "et;spawnve() arg 2 must contain only strings",
3324 Py_FileSystemDefaultEncoding,
3325 &argvlist[i]))
3326 {
3327 lastarg = i;
3328 goto fail_1;
3329 }
3330 }
3331 lastarg = argc;
3332 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003333
Victor Stinnerd6f85422010-05-05 23:33:33 +00003334 i = PyMapping_Size(env);
3335 if (i < 0)
3336 goto fail_1;
3337 envlist = PyMem_NEW(char *, i + 1);
3338 if (envlist == NULL) {
3339 PyErr_NoMemory();
3340 goto fail_1;
3341 }
3342 envc = 0;
3343 keys = PyMapping_Keys(env);
3344 vals = PyMapping_Values(env);
3345 if (!keys || !vals)
3346 goto fail_2;
3347 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3348 PyErr_SetString(PyExc_TypeError,
3349 "spawnve(): env.keys() or env.values() is not a list");
3350 goto fail_2;
3351 }
Tim Peters5aa91602002-01-30 05:46:57 +00003352
Victor Stinnerd6f85422010-05-05 23:33:33 +00003353 for (pos = 0; pos < i; pos++) {
3354 char *p, *k, *v;
3355 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003356
Victor Stinnerd6f85422010-05-05 23:33:33 +00003357 key = PyList_GetItem(keys, pos);
3358 val = PyList_GetItem(vals, pos);
3359 if (!key || !val)
3360 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003361
Victor Stinnerd6f85422010-05-05 23:33:33 +00003362 if (!PyArg_Parse(
3363 key,
3364 "s;spawnve() arg 3 contains a non-string key",
3365 &k) ||
3366 !PyArg_Parse(
3367 val,
3368 "s;spawnve() arg 3 contains a non-string value",
3369 &v))
3370 {
3371 goto fail_2;
3372 }
3373 len = PyString_Size(key) + PyString_Size(val) + 2;
3374 p = PyMem_NEW(char, len);
3375 if (p == NULL) {
3376 PyErr_NoMemory();
3377 goto fail_2;
3378 }
3379 PyOS_snprintf(p, len, "%s=%s", k, v);
3380 envlist[envc++] = p;
3381 }
3382 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003383
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003384#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003385 Py_BEGIN_ALLOW_THREADS
3386 spawnval = spawnve(mode, path, argvlist, envlist);
3387 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003388#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003389 if (mode == _OLD_P_OVERLAY)
3390 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003391
Victor Stinnerd6f85422010-05-05 23:33:33 +00003392 Py_BEGIN_ALLOW_THREADS
3393 spawnval = _spawnve(mode, path, argvlist, envlist);
3394 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003395#endif
Tim Peters25059d32001-12-07 20:35:43 +00003396
Victor Stinnerd6f85422010-05-05 23:33:33 +00003397 if (spawnval == -1)
3398 (void) posix_error();
3399 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003400#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003401 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003402#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003403 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003404#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003405
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003406 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003407 while (--envc >= 0)
3408 PyMem_DEL(envlist[envc]);
3409 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003410 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003411 free_string_array(argvlist, lastarg);
3412 Py_XDECREF(vals);
3413 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003414 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003415 PyMem_Free(path);
3416 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003417}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003418
3419/* OS/2 supports spawnvp & spawnvpe natively */
3420#if defined(PYOS_OS2)
3421PyDoc_STRVAR(posix_spawnvp__doc__,
3422"spawnvp(mode, file, args)\n\n\
3423Execute the program 'file' in a new process, using the environment\n\
3424search path to find the file.\n\
3425\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003426 mode: mode of process creation\n\
3427 file: executable file name\n\
3428 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003429
3430static PyObject *
3431posix_spawnvp(PyObject *self, PyObject *args)
3432{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003433 char *path;
3434 PyObject *argv;
3435 char **argvlist;
3436 int mode, i, argc;
3437 Py_intptr_t spawnval;
3438 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003439
Victor Stinnerd6f85422010-05-05 23:33:33 +00003440 /* spawnvp has three arguments: (mode, path, argv), where
3441 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003442
Victor Stinnerd6f85422010-05-05 23:33:33 +00003443 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3444 Py_FileSystemDefaultEncoding,
3445 &path, &argv))
3446 return NULL;
3447 if (PyList_Check(argv)) {
3448 argc = PyList_Size(argv);
3449 getitem = PyList_GetItem;
3450 }
3451 else if (PyTuple_Check(argv)) {
3452 argc = PyTuple_Size(argv);
3453 getitem = PyTuple_GetItem;
3454 }
3455 else {
3456 PyErr_SetString(PyExc_TypeError,
3457 "spawnvp() arg 2 must be a tuple or list");
3458 PyMem_Free(path);
3459 return NULL;
3460 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003461
Victor Stinnerd6f85422010-05-05 23:33:33 +00003462 argvlist = PyMem_NEW(char *, argc+1);
3463 if (argvlist == NULL) {
3464 PyMem_Free(path);
3465 return PyErr_NoMemory();
3466 }
3467 for (i = 0; i < argc; i++) {
3468 if (!PyArg_Parse((*getitem)(argv, i), "et",
3469 Py_FileSystemDefaultEncoding,
3470 &argvlist[i])) {
3471 free_string_array(argvlist, i);
3472 PyErr_SetString(
3473 PyExc_TypeError,
3474 "spawnvp() arg 2 must contain only strings");
3475 PyMem_Free(path);
3476 return NULL;
3477 }
3478 }
3479 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480
Victor Stinnerd6f85422010-05-05 23:33:33 +00003481 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003482#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003484#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003486#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003487 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003488
Victor Stinnerd6f85422010-05-05 23:33:33 +00003489 free_string_array(argvlist, argc);
3490 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003491
Victor Stinnerd6f85422010-05-05 23:33:33 +00003492 if (spawnval == -1)
3493 return posix_error();
3494 else
3495 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003496}
3497
3498
3499PyDoc_STRVAR(posix_spawnvpe__doc__,
3500"spawnvpe(mode, file, args, env)\n\n\
3501Execute the program 'file' in a new process, using the environment\n\
3502search path to find the file.\n\
3503\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003504 mode: mode of process creation\n\
3505 file: executable file name\n\
3506 args: tuple or list of arguments\n\
3507 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003508
3509static PyObject *
3510posix_spawnvpe(PyObject *self, PyObject *args)
3511{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003512 char *path;
3513 PyObject *argv, *env;
3514 char **argvlist;
3515 char **envlist;
3516 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3517 int mode, i, pos, argc, envc;
3518 Py_intptr_t spawnval;
3519 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3520 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003521
Victor Stinnerd6f85422010-05-05 23:33:33 +00003522 /* spawnvpe has four arguments: (mode, path, argv, env), where
3523 argv is a list or tuple of strings and env is a dictionary
3524 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003525
Victor Stinnerd6f85422010-05-05 23:33:33 +00003526 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3527 Py_FileSystemDefaultEncoding,
3528 &path, &argv, &env))
3529 return NULL;
3530 if (PyList_Check(argv)) {
3531 argc = PyList_Size(argv);
3532 getitem = PyList_GetItem;
3533 }
3534 else if (PyTuple_Check(argv)) {
3535 argc = PyTuple_Size(argv);
3536 getitem = PyTuple_GetItem;
3537 }
3538 else {
3539 PyErr_SetString(PyExc_TypeError,
3540 "spawnvpe() arg 2 must be a tuple or list");
3541 goto fail_0;
3542 }
3543 if (!PyMapping_Check(env)) {
3544 PyErr_SetString(PyExc_TypeError,
3545 "spawnvpe() arg 3 must be a mapping object");
3546 goto fail_0;
3547 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003548
Victor Stinnerd6f85422010-05-05 23:33:33 +00003549 argvlist = PyMem_NEW(char *, argc+1);
3550 if (argvlist == NULL) {
3551 PyErr_NoMemory();
3552 goto fail_0;
3553 }
3554 for (i = 0; i < argc; i++) {
3555 if (!PyArg_Parse((*getitem)(argv, i),
3556 "et;spawnvpe() arg 2 must contain only strings",
3557 Py_FileSystemDefaultEncoding,
3558 &argvlist[i]))
3559 {
3560 lastarg = i;
3561 goto fail_1;
3562 }
3563 }
3564 lastarg = argc;
3565 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003566
Victor Stinnerd6f85422010-05-05 23:33:33 +00003567 i = PyMapping_Size(env);
3568 if (i < 0)
3569 goto fail_1;
3570 envlist = PyMem_NEW(char *, i + 1);
3571 if (envlist == NULL) {
3572 PyErr_NoMemory();
3573 goto fail_1;
3574 }
3575 envc = 0;
3576 keys = PyMapping_Keys(env);
3577 vals = PyMapping_Values(env);
3578 if (!keys || !vals)
3579 goto fail_2;
3580 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3581 PyErr_SetString(PyExc_TypeError,
3582 "spawnvpe(): env.keys() or env.values() is not a list");
3583 goto fail_2;
3584 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003585
Victor Stinnerd6f85422010-05-05 23:33:33 +00003586 for (pos = 0; pos < i; pos++) {
3587 char *p, *k, *v;
3588 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003589
Victor Stinnerd6f85422010-05-05 23:33:33 +00003590 key = PyList_GetItem(keys, pos);
3591 val = PyList_GetItem(vals, pos);
3592 if (!key || !val)
3593 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003594
Victor Stinnerd6f85422010-05-05 23:33:33 +00003595 if (!PyArg_Parse(
3596 key,
3597 "s;spawnvpe() arg 3 contains a non-string key",
3598 &k) ||
3599 !PyArg_Parse(
3600 val,
3601 "s;spawnvpe() arg 3 contains a non-string value",
3602 &v))
3603 {
3604 goto fail_2;
3605 }
3606 len = PyString_Size(key) + PyString_Size(val) + 2;
3607 p = PyMem_NEW(char, len);
3608 if (p == NULL) {
3609 PyErr_NoMemory();
3610 goto fail_2;
3611 }
3612 PyOS_snprintf(p, len, "%s=%s", k, v);
3613 envlist[envc++] = p;
3614 }
3615 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003616
Victor Stinnerd6f85422010-05-05 23:33:33 +00003617 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003618#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003619 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003621 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003624
Victor Stinnerd6f85422010-05-05 23:33:33 +00003625 if (spawnval == -1)
3626 (void) posix_error();
3627 else
3628 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003629
3630 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003631 while (--envc >= 0)
3632 PyMem_DEL(envlist[envc]);
3633 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003634 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003635 free_string_array(argvlist, lastarg);
3636 Py_XDECREF(vals);
3637 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003638 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003639 PyMem_Free(path);
3640 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003641}
3642#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003643#endif /* HAVE_SPAWNV */
3644
3645
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003646#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003647PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003648"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003649Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3650\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003651Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003652
3653static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003654posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003655{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003656 pid_t pid;
3657 int result = 0;
3658 _PyImport_AcquireLock();
3659 pid = fork1();
3660 if (pid == 0) {
3661 /* child: this clobbers and resets the import lock. */
3662 PyOS_AfterFork();
3663 } else {
3664 /* parent: release the import lock. */
3665 result = _PyImport_ReleaseLock();
3666 }
3667 if (pid == -1)
3668 return posix_error();
3669 if (result < 0) {
3670 /* Don't clobber the OSError if the fork failed. */
3671 PyErr_SetString(PyExc_RuntimeError,
3672 "not holding the import lock");
3673 return NULL;
3674 }
3675 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003676}
3677#endif
3678
3679
Guido van Rossumad0ee831995-03-01 10:34:45 +00003680#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003681PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003682"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003684Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003685
Barry Warsaw53699e91996-12-10 23:23:01 +00003686static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003687posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003688{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003689 pid_t pid;
3690 int result = 0;
3691 _PyImport_AcquireLock();
3692 pid = fork();
3693 if (pid == 0) {
3694 /* child: this clobbers and resets the import lock. */
3695 PyOS_AfterFork();
3696 } else {
3697 /* parent: release the import lock. */
3698 result = _PyImport_ReleaseLock();
3699 }
3700 if (pid == -1)
3701 return posix_error();
3702 if (result < 0) {
3703 /* Don't clobber the OSError if the fork failed. */
3704 PyErr_SetString(PyExc_RuntimeError,
3705 "not holding the import lock");
3706 return NULL;
3707 }
3708 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003709}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003710#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003711
Neal Norwitzb59798b2003-03-21 01:43:31 +00003712/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003713/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3714#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003715#define DEV_PTY_FILE "/dev/ptc"
3716#define HAVE_DEV_PTMX
3717#else
3718#define DEV_PTY_FILE "/dev/ptmx"
3719#endif
3720
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003721#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003722#ifdef HAVE_PTY_H
3723#include <pty.h>
3724#else
3725#ifdef HAVE_LIBUTIL_H
3726#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003727#else
3728#ifdef HAVE_UTIL_H
3729#include <util.h>
3730#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003731#endif /* HAVE_LIBUTIL_H */
3732#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003733#ifdef HAVE_STROPTS_H
3734#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003735#endif
3736#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003737
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003738#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003740"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003741Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003742
3743static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003744posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003745{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003746 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003747#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003748 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003749#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003750#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003751 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003752#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003753 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003754#endif
3755#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003756
Thomas Wouters70c21a12000-07-14 14:28:33 +00003757#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003758 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3759 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003760#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003761 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3762 if (slave_name == NULL)
3763 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003764
Victor Stinnerd6f85422010-05-05 23:33:33 +00003765 slave_fd = open(slave_name, O_RDWR);
3766 if (slave_fd < 0)
3767 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003768#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003769 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3770 if (master_fd < 0)
3771 return posix_error();
3772 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3773 /* change permission of slave */
3774 if (grantpt(master_fd) < 0) {
3775 PyOS_setsig(SIGCHLD, sig_saved);
3776 return posix_error();
3777 }
3778 /* unlock slave */
3779 if (unlockpt(master_fd) < 0) {
3780 PyOS_setsig(SIGCHLD, sig_saved);
3781 return posix_error();
3782 }
3783 PyOS_setsig(SIGCHLD, sig_saved);
3784 slave_name = ptsname(master_fd); /* get name of slave */
3785 if (slave_name == NULL)
3786 return posix_error();
3787 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3788 if (slave_fd < 0)
3789 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003790#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003791 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3792 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003793#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003794 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003795#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003796#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003797#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003798
Victor Stinnerd6f85422010-05-05 23:33:33 +00003799 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003800
Fred Drake8cef4cf2000-06-28 16:40:38 +00003801}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003802#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003803
3804#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003805PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003806"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003807Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3808Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003809To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003810
3811static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003812posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003813{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003814 int master_fd = -1, result = 0;
3815 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003816
Victor Stinnerd6f85422010-05-05 23:33:33 +00003817 _PyImport_AcquireLock();
3818 pid = forkpty(&master_fd, NULL, NULL, NULL);
3819 if (pid == 0) {
3820 /* child: this clobbers and resets the import lock. */
3821 PyOS_AfterFork();
3822 } else {
3823 /* parent: release the import lock. */
3824 result = _PyImport_ReleaseLock();
3825 }
3826 if (pid == -1)
3827 return posix_error();
3828 if (result < 0) {
3829 /* Don't clobber the OSError if the fork failed. */
3830 PyErr_SetString(PyExc_RuntimeError,
3831 "not holding the import lock");
3832 return NULL;
3833 }
3834 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003835}
3836#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003837
Guido van Rossumad0ee831995-03-01 10:34:45 +00003838#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003840"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003841Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842
Barry Warsaw53699e91996-12-10 23:23:01 +00003843static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003844posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003845{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003846 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003847}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003848#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003850
Guido van Rossumad0ee831995-03-01 10:34:45 +00003851#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003853"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003854Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Barry Warsaw53699e91996-12-10 23:23:01 +00003856static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003857posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003858{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003859 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003860}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003861#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003863
Guido van Rossumad0ee831995-03-01 10:34:45 +00003864#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003866"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003867Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003868
Barry Warsaw53699e91996-12-10 23:23:01 +00003869static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003870posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003871{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003872 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003873}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003874#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003878"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003880
Barry Warsaw53699e91996-12-10 23:23:01 +00003881static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003882posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003883{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003884 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003885}
3886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887
Fred Drakec9680921999-12-13 16:37:25 +00003888#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003892
3893static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003894posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003895{
3896 PyObject *result = NULL;
3897
Fred Drakec9680921999-12-13 16:37:25 +00003898#ifdef NGROUPS_MAX
3899#define MAX_GROUPS NGROUPS_MAX
3900#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003901 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003902#define MAX_GROUPS 64
3903#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003904 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003905
3906 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
3907 * This is a helper variable to store the intermediate result when
3908 * that happens.
3909 *
3910 * To keep the code readable the OSX behaviour is unconditional,
3911 * according to the POSIX spec this should be safe on all unix-y
3912 * systems.
3913 */
3914 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003915 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003916
Victor Stinnerd6f85422010-05-05 23:33:33 +00003917 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003918 if (n < 0) {
3919 if (errno == EINVAL) {
3920 n = getgroups(0, NULL);
3921 if (n == -1) {
3922 return posix_error();
3923 }
3924 if (n == 0) {
3925 /* Avoid malloc(0) */
3926 alt_grouplist = grouplist;
3927 } else {
3928 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
3929 if (alt_grouplist == NULL) {
3930 errno = EINVAL;
3931 return posix_error();
3932 }
3933 n = getgroups(n, alt_grouplist);
3934 if (n == -1) {
3935 PyMem_Free(alt_grouplist);
3936 return posix_error();
3937 }
3938 }
3939 } else {
3940 return posix_error();
3941 }
3942 }
3943 result = PyList_New(n);
3944 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00003945 int i;
3946 for (i = 0; i < n; ++i) {
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003947 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003948 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00003949 Py_DECREF(result);
3950 result = NULL;
3951 break;
Fred Drakec9680921999-12-13 16:37:25 +00003952 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003953 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003954 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003955 }
3956
3957 if (alt_grouplist != grouplist) {
3958 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003959 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003960
Fred Drakec9680921999-12-13 16:37:25 +00003961 return result;
3962}
3963#endif
3964
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003965#ifdef HAVE_INITGROUPS
3966PyDoc_STRVAR(posix_initgroups__doc__,
3967"initgroups(username, gid) -> None\n\n\
3968Call the system initgroups() to initialize the group access list with all of\n\
3969the groups of which the specified username is a member, plus the specified\n\
3970group id.");
3971
3972static PyObject *
3973posix_initgroups(PyObject *self, PyObject *args)
3974{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003975 char *username;
3976 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003977
Victor Stinnerd6f85422010-05-05 23:33:33 +00003978 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3979 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003980
Victor Stinnerd6f85422010-05-05 23:33:33 +00003981 if (initgroups(username, (gid_t) gid) == -1)
3982 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003983
Victor Stinnerd6f85422010-05-05 23:33:33 +00003984 Py_INCREF(Py_None);
3985 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003986}
3987#endif
3988
Martin v. Löwis606edc12002-06-13 21:09:11 +00003989#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003990PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003991"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003992Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003993
3994static PyObject *
3995posix_getpgid(PyObject *self, PyObject *args)
3996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 pid_t pid, pgid;
3998 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3999 return NULL;
4000 pgid = getpgid(pid);
4001 if (pgid < 0)
4002 return posix_error();
4003 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004004}
4005#endif /* HAVE_GETPGID */
4006
4007
Guido van Rossumb6775db1994-08-01 11:34:53 +00004008#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004010"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004011Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Barry Warsaw53699e91996-12-10 23:23:01 +00004013static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004014posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004015{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004016#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004017 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004018#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004019 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004020#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004021}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004022#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004024
Guido van Rossumb6775db1994-08-01 11:34:53 +00004025#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004026PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004027"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004028Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004029
Barry Warsaw53699e91996-12-10 23:23:01 +00004030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004031posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004032{
Guido van Rossum64933891994-10-20 21:56:42 +00004033#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004034 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004035#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004036 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004037#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004038 return posix_error();
4039 Py_INCREF(Py_None);
4040 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004041}
4042
Guido van Rossumb6775db1994-08-01 11:34:53 +00004043#endif /* HAVE_SETPGRP */
4044
Guido van Rossumad0ee831995-03-01 10:34:45 +00004045#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004047"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004048Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004049
Barry Warsaw53699e91996-12-10 23:23:01 +00004050static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004051posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004052{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004053 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004055#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
Fred Drake12c6e2d1999-12-14 21:25:03 +00004058#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004060"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004062
4063static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004064posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004065{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004066 PyObject *result = NULL;
4067 char *name;
4068 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004069
Victor Stinnerd6f85422010-05-05 23:33:33 +00004070 errno = 0;
4071 name = getlogin();
4072 if (name == NULL) {
4073 if (errno)
4074 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004075 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004076 PyErr_SetString(PyExc_OSError,
4077 "unable to determine login name");
4078 }
4079 else
4080 result = PyString_FromString(name);
4081 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004082
Fred Drake12c6e2d1999-12-14 21:25:03 +00004083 return result;
4084}
4085#endif
4086
Guido van Rossumad0ee831995-03-01 10:34:45 +00004087#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004089"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004090Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004091
Barry Warsaw53699e91996-12-10 23:23:01 +00004092static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004093posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004094{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004095 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004096}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004097#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004098
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004099
Guido van Rossumad0ee831995-03-01 10:34:45 +00004100#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004102"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004103Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Barry Warsaw53699e91996-12-10 23:23:01 +00004105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004106posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004107{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004108 pid_t pid;
4109 int sig;
4110 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4111 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004112#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004113 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4114 APIRET rc;
4115 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004116 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004117
4118 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4119 APIRET rc;
4120 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004121 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122
4123 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004124 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004125#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004126 if (kill(pid, sig) == -1)
4127 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004128#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004129 Py_INCREF(Py_None);
4130 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004131}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004132#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004133
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004134#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004136"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004137Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004138
4139static PyObject *
4140posix_killpg(PyObject *self, PyObject *args)
4141{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004142 int sig;
4143 pid_t pgid;
4144 /* XXX some man pages make the `pgid` parameter an int, others
4145 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4146 take the same type. Moreover, pid_t is always at least as wide as
4147 int (else compilation of this module fails), which is safe. */
4148 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4149 return NULL;
4150 if (killpg(pgid, sig) == -1)
4151 return posix_error();
4152 Py_INCREF(Py_None);
4153 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004154}
4155#endif
4156
Brian Curtine5aa8862010-04-02 23:26:06 +00004157#ifdef MS_WINDOWS
4158PyDoc_STRVAR(win32_kill__doc__,
4159"kill(pid, sig)\n\n\
4160Kill a process with a signal.");
4161
4162static PyObject *
4163win32_kill(PyObject *self, PyObject *args)
4164{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004165 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004166 DWORD pid, sig, err;
4167 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004168
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4170 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004171
Victor Stinnerd6f85422010-05-05 23:33:33 +00004172 /* Console processes which share a common console can be sent CTRL+C or
4173 CTRL+BREAK events, provided they handle said events. */
4174 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4175 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4176 err = GetLastError();
4177 return PyErr_SetFromWindowsErr(err);
4178 }
4179 else
4180 Py_RETURN_NONE;
4181 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004182
Victor Stinnerd6f85422010-05-05 23:33:33 +00004183 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4184 attempt to open and terminate the process. */
4185 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4186 if (handle == NULL) {
4187 err = GetLastError();
4188 return PyErr_SetFromWindowsErr(err);
4189 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004190
Victor Stinnerd6f85422010-05-05 23:33:33 +00004191 if (TerminateProcess(handle, sig) == 0) {
4192 err = GetLastError();
4193 result = PyErr_SetFromWindowsErr(err);
4194 } else {
4195 Py_INCREF(Py_None);
4196 result = Py_None;
4197 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004198
Victor Stinnerd6f85422010-05-05 23:33:33 +00004199 CloseHandle(handle);
4200 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004201}
Brian Curtincaea7e82011-06-08 19:29:53 -05004202
4203static PyObject *
4204posix__isdir(PyObject *self, PyObject *args)
4205{
4206 PyObject *opath;
4207 char *path;
4208 PyUnicodeObject *po;
4209 DWORD attributes;
4210
4211 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
4212 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
4213
4214 attributes = GetFileAttributesW(wpath);
4215 if (attributes == INVALID_FILE_ATTRIBUTES)
4216 Py_RETURN_FALSE;
4217 goto check;
4218 }
4219 /* Drop the argument parsing error as narrow strings
4220 are also valid. */
4221 PyErr_Clear();
4222
4223 if (!PyArg_ParseTuple(args, "et:_isdir",
4224 Py_FileSystemDefaultEncoding, &path))
4225 return NULL;
4226
4227 attributes = GetFileAttributesA(path);
4228 if (attributes == INVALID_FILE_ATTRIBUTES)
4229 Py_RETURN_FALSE;
4230
4231check:
4232 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
4233 Py_RETURN_TRUE;
4234 else
4235 Py_RETURN_FALSE;
4236}
Brian Curtine5aa8862010-04-02 23:26:06 +00004237#endif /* MS_WINDOWS */
4238
Guido van Rossumc0125471996-06-28 18:55:32 +00004239#ifdef HAVE_PLOCK
4240
4241#ifdef HAVE_SYS_LOCK_H
4242#include <sys/lock.h>
4243#endif
4244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004246"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004247Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004248
Barry Warsaw53699e91996-12-10 23:23:01 +00004249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004250posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004251{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004252 int op;
4253 if (!PyArg_ParseTuple(args, "i:plock", &op))
4254 return NULL;
4255 if (plock(op) == -1)
4256 return posix_error();
4257 Py_INCREF(Py_None);
4258 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004259}
4260#endif
4261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004263#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004264PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004265"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004268#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004269#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004270static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004271async_system(const char *command)
4272{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004273 char errormsg[256], args[1024];
4274 RESULTCODES rcodes;
4275 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004276
Victor Stinnerd6f85422010-05-05 23:33:33 +00004277 char *shell = getenv("COMSPEC");
4278 if (!shell)
4279 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004280
Victor Stinnerd6f85422010-05-05 23:33:33 +00004281 /* avoid overflowing the argument buffer */
4282 if (strlen(shell) + 3 + strlen(command) >= 1024)
4283 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004284
Victor Stinnerd6f85422010-05-05 23:33:33 +00004285 args[0] = '\0';
4286 strcat(args, shell);
4287 strcat(args, "/c ");
4288 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004289
Victor Stinnerd6f85422010-05-05 23:33:33 +00004290 /* execute asynchronously, inheriting the environment */
4291 rc = DosExecPgm(errormsg,
4292 sizeof(errormsg),
4293 EXEC_ASYNC,
4294 args,
4295 NULL,
4296 &rcodes,
4297 shell);
4298 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004299}
4300
Guido van Rossumd48f2521997-12-05 22:19:34 +00004301static FILE *
4302popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004303{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004304 int oldfd, tgtfd;
4305 HFILE pipeh[2];
4306 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004307
Victor Stinnerd6f85422010-05-05 23:33:33 +00004308 /* mode determines which of stdin or stdout is reconnected to
4309 * the pipe to the child
4310 */
4311 if (strchr(mode, 'r') != NULL) {
4312 tgt_fd = 1; /* stdout */
4313 } else if (strchr(mode, 'w')) {
4314 tgt_fd = 0; /* stdin */
4315 } else {
4316 *err = ERROR_INVALID_ACCESS;
4317 return NULL;
4318 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004319
Victor Stinnerd6f85422010-05-05 23:33:33 +00004320 /* setup the pipe */
4321 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4322 *err = rc;
4323 return NULL;
4324 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004325
Victor Stinnerd6f85422010-05-05 23:33:33 +00004326 /* prevent other threads accessing stdio */
4327 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004328
Victor Stinnerd6f85422010-05-05 23:33:33 +00004329 /* reconnect stdio and execute child */
4330 oldfd = dup(tgtfd);
4331 close(tgtfd);
4332 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4333 DosClose(pipeh[tgtfd]);
4334 rc = async_system(command);
4335 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004336
Victor Stinnerd6f85422010-05-05 23:33:33 +00004337 /* restore stdio */
4338 dup2(oldfd, tgtfd);
4339 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004340
Victor Stinnerd6f85422010-05-05 23:33:33 +00004341 /* allow other threads access to stdio */
4342 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004343
Victor Stinnerd6f85422010-05-05 23:33:33 +00004344 /* if execution of child was successful return file stream */
4345 if (rc == NO_ERROR)
4346 return fdopen(pipeh[1 - tgtfd], mode);
4347 else {
4348 DosClose(pipeh[1 - tgtfd]);
4349 *err = rc;
4350 return NULL;
4351 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004352}
4353
4354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004355posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004356{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004357 char *name;
4358 char *mode = "r";
4359 int err, bufsize = -1;
4360 FILE *fp;
4361 PyObject *f;
4362 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4363 return NULL;
4364 Py_BEGIN_ALLOW_THREADS
4365 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4366 Py_END_ALLOW_THREADS
4367 if (fp == NULL)
4368 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004369
Victor Stinnerd6f85422010-05-05 23:33:33 +00004370 f = PyFile_FromFile(fp, name, mode, fclose);
4371 if (f != NULL)
4372 PyFile_SetBufSize(f, bufsize);
4373 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004374}
4375
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004376#elif defined(PYCC_GCC)
4377
4378/* standard posix version of popen() support */
4379static PyObject *
4380posix_popen(PyObject *self, PyObject *args)
4381{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004382 char *name;
4383 char *mode = "r";
4384 int bufsize = -1;
4385 FILE *fp;
4386 PyObject *f;
4387 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4388 return NULL;
4389 Py_BEGIN_ALLOW_THREADS
4390 fp = popen(name, mode);
4391 Py_END_ALLOW_THREADS
4392 if (fp == NULL)
4393 return posix_error();
4394 f = PyFile_FromFile(fp, name, mode, pclose);
4395 if (f != NULL)
4396 PyFile_SetBufSize(f, bufsize);
4397 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004398}
4399
4400/* fork() under OS/2 has lots'o'warts
4401 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4402 * most of this code is a ripoff of the win32 code, but using the
4403 * capabilities of EMX's C library routines
4404 */
4405
4406/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4407#define POPEN_1 1
4408#define POPEN_2 2
4409#define POPEN_3 3
4410#define POPEN_4 4
4411
4412static PyObject *_PyPopen(char *, int, int, int);
4413static int _PyPclose(FILE *file);
4414
4415/*
4416 * Internal dictionary mapping popen* file pointers to process handles,
4417 * for use when retrieving the process exit code. See _PyPclose() below
4418 * for more information on this dictionary's use.
4419 */
4420static PyObject *_PyPopenProcs = NULL;
4421
4422/* os2emx version of popen2()
4423 *
4424 * The result of this function is a pipe (file) connected to the
4425 * process's stdin, and a pipe connected to the process's stdout.
4426 */
4427
4428static PyObject *
4429os2emx_popen2(PyObject *self, PyObject *args)
4430{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004431 PyObject *f;
4432 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004433
Victor Stinnerd6f85422010-05-05 23:33:33 +00004434 char *cmdstring;
4435 char *mode = "t";
4436 int bufsize = -1;
4437 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4438 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004439
Victor Stinnerd6f85422010-05-05 23:33:33 +00004440 if (*mode == 't')
4441 tm = O_TEXT;
4442 else if (*mode != 'b') {
4443 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4444 return NULL;
4445 } else
4446 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004447
Victor Stinnerd6f85422010-05-05 23:33:33 +00004448 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004449
Victor Stinnerd6f85422010-05-05 23:33:33 +00004450 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004451}
4452
4453/*
4454 * Variation on os2emx.popen2
4455 *
4456 * The result of this function is 3 pipes - the process's stdin,
4457 * stdout and stderr
4458 */
4459
4460static PyObject *
4461os2emx_popen3(PyObject *self, PyObject *args)
4462{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004463 PyObject *f;
4464 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004465
Victor Stinnerd6f85422010-05-05 23:33:33 +00004466 char *cmdstring;
4467 char *mode = "t";
4468 int bufsize = -1;
4469 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4470 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004471
Victor Stinnerd6f85422010-05-05 23:33:33 +00004472 if (*mode == 't')
4473 tm = O_TEXT;
4474 else if (*mode != 'b') {
4475 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4476 return NULL;
4477 } else
4478 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004479
Victor Stinnerd6f85422010-05-05 23:33:33 +00004480 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004481
Victor Stinnerd6f85422010-05-05 23:33:33 +00004482 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004483}
4484
4485/*
4486 * Variation on os2emx.popen2
4487 *
Tim Peters11b23062003-04-23 02:39:17 +00004488 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004489 * and stdout+stderr combined as a single pipe.
4490 */
4491
4492static PyObject *
4493os2emx_popen4(PyObject *self, PyObject *args)
4494{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004495 PyObject *f;
4496 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004497
Victor Stinnerd6f85422010-05-05 23:33:33 +00004498 char *cmdstring;
4499 char *mode = "t";
4500 int bufsize = -1;
4501 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4502 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004503
Victor Stinnerd6f85422010-05-05 23:33:33 +00004504 if (*mode == 't')
4505 tm = O_TEXT;
4506 else if (*mode != 'b') {
4507 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4508 return NULL;
4509 } else
4510 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004511
Victor Stinnerd6f85422010-05-05 23:33:33 +00004512 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004513
Victor Stinnerd6f85422010-05-05 23:33:33 +00004514 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004515}
4516
4517/* a couple of structures for convenient handling of multiple
4518 * file handles and pipes
4519 */
4520struct file_ref
4521{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004522 int handle;
4523 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004524};
4525
4526struct pipe_ref
4527{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004528 int rd;
4529 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004530};
4531
4532/* The following code is derived from the win32 code */
4533
4534static PyObject *
4535_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4536{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004537 struct file_ref stdio[3];
4538 struct pipe_ref p_fd[3];
4539 FILE *p_s[3];
4540 int file_count, i, pipe_err;
4541 pid_t pipe_pid;
4542 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4543 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004544
Victor Stinnerd6f85422010-05-05 23:33:33 +00004545 /* file modes for subsequent fdopen's on pipe handles */
4546 if (mode == O_TEXT)
4547 {
4548 rd_mode = "rt";
4549 wr_mode = "wt";
4550 }
4551 else
4552 {
4553 rd_mode = "rb";
4554 wr_mode = "wb";
4555 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004556
Victor Stinnerd6f85422010-05-05 23:33:33 +00004557 /* prepare shell references */
4558 if ((shell = getenv("EMXSHELL")) == NULL)
4559 if ((shell = getenv("COMSPEC")) == NULL)
4560 {
4561 errno = ENOENT;
4562 return posix_error();
4563 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004564
Victor Stinnerd6f85422010-05-05 23:33:33 +00004565 sh_name = _getname(shell);
4566 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4567 opt = "/c";
4568 else
4569 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004570
Victor Stinnerd6f85422010-05-05 23:33:33 +00004571 /* save current stdio fds + their flags, and set not inheritable */
4572 i = pipe_err = 0;
4573 while (pipe_err >= 0 && i < 3)
4574 {
4575 pipe_err = stdio[i].handle = dup(i);
4576 stdio[i].flags = fcntl(i, F_GETFD, 0);
4577 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4578 i++;
4579 }
4580 if (pipe_err < 0)
4581 {
4582 /* didn't get them all saved - clean up and bail out */
4583 int saved_err = errno;
4584 while (i-- > 0)
4585 {
4586 close(stdio[i].handle);
4587 }
4588 errno = saved_err;
4589 return posix_error();
4590 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004591
Victor Stinnerd6f85422010-05-05 23:33:33 +00004592 /* create pipe ends */
4593 file_count = 2;
4594 if (n == POPEN_3)
4595 file_count = 3;
4596 i = pipe_err = 0;
4597 while ((pipe_err == 0) && (i < file_count))
4598 pipe_err = pipe((int *)&p_fd[i++]);
4599 if (pipe_err < 0)
4600 {
4601 /* didn't get them all made - clean up and bail out */
4602 while (i-- > 0)
4603 {
4604 close(p_fd[i].wr);
4605 close(p_fd[i].rd);
4606 }
4607 errno = EPIPE;
4608 return posix_error();
4609 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004610
Victor Stinnerd6f85422010-05-05 23:33:33 +00004611 /* change the actual standard IO streams over temporarily,
4612 * making the retained pipe ends non-inheritable
4613 */
4614 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615
Victor Stinnerd6f85422010-05-05 23:33:33 +00004616 /* - stdin */
4617 if (dup2(p_fd[0].rd, 0) == 0)
4618 {
4619 close(p_fd[0].rd);
4620 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4621 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4622 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4623 {
4624 close(p_fd[0].wr);
4625 pipe_err = -1;
4626 }
4627 }
4628 else
4629 {
4630 pipe_err = -1;
4631 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004632
Victor Stinnerd6f85422010-05-05 23:33:33 +00004633 /* - stdout */
4634 if (pipe_err == 0)
4635 {
4636 if (dup2(p_fd[1].wr, 1) == 1)
4637 {
4638 close(p_fd[1].wr);
4639 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4640 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4641 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4642 {
4643 close(p_fd[1].rd);
4644 pipe_err = -1;
4645 }
4646 }
4647 else
4648 {
4649 pipe_err = -1;
4650 }
4651 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004652
Victor Stinnerd6f85422010-05-05 23:33:33 +00004653 /* - stderr, as required */
4654 if (pipe_err == 0)
4655 switch (n)
4656 {
4657 case POPEN_3:
4658 {
4659 if (dup2(p_fd[2].wr, 2) == 2)
4660 {
4661 close(p_fd[2].wr);
4662 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4663 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4664 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4665 {
4666 close(p_fd[2].rd);
4667 pipe_err = -1;
4668 }
4669 }
4670 else
4671 {
4672 pipe_err = -1;
4673 }
4674 break;
4675 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004676
Victor Stinnerd6f85422010-05-05 23:33:33 +00004677 case POPEN_4:
4678 {
4679 if (dup2(1, 2) != 2)
4680 {
4681 pipe_err = -1;
4682 }
4683 break;
4684 }
4685 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004686
Victor Stinnerd6f85422010-05-05 23:33:33 +00004687 /* spawn the child process */
4688 if (pipe_err == 0)
4689 {
4690 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4691 if (pipe_pid == -1)
4692 {
4693 pipe_err = -1;
4694 }
4695 else
4696 {
4697 /* save the PID into the FILE structure
4698 * NOTE: this implementation doesn't actually
4699 * take advantage of this, but do it for
4700 * completeness - AIM Apr01
4701 */
4702 for (i = 0; i < file_count; i++)
4703 p_s[i]->_pid = pipe_pid;
4704 }
4705 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004706
Victor Stinnerd6f85422010-05-05 23:33:33 +00004707 /* reset standard IO to normal */
4708 for (i = 0; i < 3; i++)
4709 {
4710 dup2(stdio[i].handle, i);
4711 fcntl(i, F_SETFD, stdio[i].flags);
4712 close(stdio[i].handle);
4713 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004714
Victor Stinnerd6f85422010-05-05 23:33:33 +00004715 /* if any remnant problems, clean up and bail out */
4716 if (pipe_err < 0)
4717 {
4718 for (i = 0; i < 3; i++)
4719 {
4720 close(p_fd[i].rd);
4721 close(p_fd[i].wr);
4722 }
4723 errno = EPIPE;
4724 return posix_error_with_filename(cmdstring);
4725 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726
Victor Stinnerd6f85422010-05-05 23:33:33 +00004727 /* build tuple of file objects to return */
4728 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4729 PyFile_SetBufSize(p_f[0], bufsize);
4730 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4731 PyFile_SetBufSize(p_f[1], bufsize);
4732 if (n == POPEN_3)
4733 {
4734 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4735 PyFile_SetBufSize(p_f[0], bufsize);
4736 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4737 }
4738 else
4739 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004740
Victor Stinnerd6f85422010-05-05 23:33:33 +00004741 /*
4742 * Insert the files we've created into the process dictionary
4743 * all referencing the list with the process handle and the
4744 * initial number of files (see description below in _PyPclose).
4745 * Since if _PyPclose later tried to wait on a process when all
4746 * handles weren't closed, it could create a deadlock with the
4747 * child, we spend some energy here to try to ensure that we
4748 * either insert all file handles into the dictionary or none
4749 * at all. It's a little clumsy with the various popen modes
4750 * and variable number of files involved.
4751 */
4752 if (!_PyPopenProcs)
4753 {
4754 _PyPopenProcs = PyDict_New();
4755 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004756
Victor Stinnerd6f85422010-05-05 23:33:33 +00004757 if (_PyPopenProcs)
4758 {
4759 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4760 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004761
Victor Stinnerd6f85422010-05-05 23:33:33 +00004762 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4763 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004764
Victor Stinnerd6f85422010-05-05 23:33:33 +00004765 procObj = PyList_New(2);
4766 pidObj = PyLong_FromPid(pipe_pid);
4767 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004768
Victor Stinnerd6f85422010-05-05 23:33:33 +00004769 if (procObj && pidObj && intObj)
4770 {
4771 PyList_SetItem(procObj, 0, pidObj);
4772 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004773
Victor Stinnerd6f85422010-05-05 23:33:33 +00004774 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4775 if (fileObj[0])
4776 {
4777 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4778 fileObj[0],
4779 procObj);
4780 }
4781 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4782 if (fileObj[1])
4783 {
4784 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4785 fileObj[1],
4786 procObj);
4787 }
4788 if (file_count >= 3)
4789 {
4790 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4791 if (fileObj[2])
4792 {
4793 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4794 fileObj[2],
4795 procObj);
4796 }
4797 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004798
Victor Stinnerd6f85422010-05-05 23:33:33 +00004799 if (ins_rc[0] < 0 || !fileObj[0] ||
4800 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4801 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4802 {
4803 /* Something failed - remove any dictionary
4804 * entries that did make it.
4805 */
4806 if (!ins_rc[0] && fileObj[0])
4807 {
4808 PyDict_DelItem(_PyPopenProcs,
4809 fileObj[0]);
4810 }
4811 if (!ins_rc[1] && fileObj[1])
4812 {
4813 PyDict_DelItem(_PyPopenProcs,
4814 fileObj[1]);
4815 }
4816 if (!ins_rc[2] && fileObj[2])
4817 {
4818 PyDict_DelItem(_PyPopenProcs,
4819 fileObj[2]);
4820 }
4821 }
4822 }
Tim Peters11b23062003-04-23 02:39:17 +00004823
Victor Stinnerd6f85422010-05-05 23:33:33 +00004824 /*
4825 * Clean up our localized references for the dictionary keys
4826 * and value since PyDict_SetItem will Py_INCREF any copies
4827 * that got placed in the dictionary.
4828 */
4829 Py_XDECREF(procObj);
4830 Py_XDECREF(fileObj[0]);
4831 Py_XDECREF(fileObj[1]);
4832 Py_XDECREF(fileObj[2]);
4833 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004834
Victor Stinnerd6f85422010-05-05 23:33:33 +00004835 /* Child is launched. */
4836 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004837}
4838
4839/*
4840 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4841 * exit code for the child process and return as a result of the close.
4842 *
4843 * This function uses the _PyPopenProcs dictionary in order to map the
4844 * input file pointer to information about the process that was
4845 * originally created by the popen* call that created the file pointer.
4846 * The dictionary uses the file pointer as a key (with one entry
4847 * inserted for each file returned by the original popen* call) and a
4848 * single list object as the value for all files from a single call.
4849 * The list object contains the Win32 process handle at [0], and a file
4850 * count at [1], which is initialized to the total number of file
4851 * handles using that list.
4852 *
4853 * This function closes whichever handle it is passed, and decrements
4854 * the file count in the dictionary for the process handle pointed to
4855 * by this file. On the last close (when the file count reaches zero),
4856 * this function will wait for the child process and then return its
4857 * exit code as the result of the close() operation. This permits the
4858 * files to be closed in any order - it is always the close() of the
4859 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004860 *
4861 * NOTE: This function is currently called with the GIL released.
4862 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004863 */
4864
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004865static int _PyPclose(FILE *file)
4866{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004867 int result;
4868 int exit_code;
4869 pid_t pipe_pid;
4870 PyObject *procObj, *pidObj, *intObj, *fileObj;
4871 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004872#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004873 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004874#endif
4875
Victor Stinnerd6f85422010-05-05 23:33:33 +00004876 /* Close the file handle first, to ensure it can't block the
4877 * child from exiting if it's the last handle.
4878 */
4879 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004880
4881#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004882 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004883#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004884 if (_PyPopenProcs)
4885 {
4886 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4887 (procObj = PyDict_GetItem(_PyPopenProcs,
4888 fileObj)) != NULL &&
4889 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4890 (intObj = PyList_GetItem(procObj,1)) != NULL)
4891 {
4892 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4893 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004894
Victor Stinnerd6f85422010-05-05 23:33:33 +00004895 if (file_count > 1)
4896 {
4897 /* Still other files referencing process */
4898 file_count--;
4899 PyList_SetItem(procObj,1,
4900 PyInt_FromLong((long) file_count));
4901 }
4902 else
4903 {
4904 /* Last file for this process */
4905 if (result != EOF &&
4906 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4907 {
4908 /* extract exit status */
4909 if (WIFEXITED(exit_code))
4910 {
4911 result = WEXITSTATUS(exit_code);
4912 }
4913 else
4914 {
4915 errno = EPIPE;
4916 result = -1;
4917 }
4918 }
4919 else
4920 {
4921 /* Indicate failure - this will cause the file object
4922 * to raise an I/O error and translate the last
4923 * error code from errno. We do have a problem with
4924 * last errors that overlap the normal errno table,
4925 * but that's a consistent problem with the file object.
4926 */
4927 result = -1;
4928 }
4929 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004930
Victor Stinnerd6f85422010-05-05 23:33:33 +00004931 /* Remove this file pointer from dictionary */
4932 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004933
Victor Stinnerd6f85422010-05-05 23:33:33 +00004934 if (PyDict_Size(_PyPopenProcs) == 0)
4935 {
4936 Py_DECREF(_PyPopenProcs);
4937 _PyPopenProcs = NULL;
4938 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004939
Victor Stinnerd6f85422010-05-05 23:33:33 +00004940 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004941
Victor Stinnerd6f85422010-05-05 23:33:33 +00004942 Py_XDECREF(fileObj);
4943 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004944
4945#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004946 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004947#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004948 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004949}
4950
4951#endif /* PYCC_??? */
4952
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004953#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004954
4955/*
4956 * Portable 'popen' replacement for Win32.
4957 *
4958 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4959 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004960 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004961 */
4962
4963#include <malloc.h>
4964#include <io.h>
4965#include <fcntl.h>
4966
4967/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4968#define POPEN_1 1
4969#define POPEN_2 2
4970#define POPEN_3 3
4971#define POPEN_4 4
4972
4973static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004974static int _PyPclose(FILE *file);
4975
4976/*
4977 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004978 * for use when retrieving the process exit code. See _PyPclose() below
4979 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004980 */
4981static PyObject *_PyPopenProcs = NULL;
4982
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004983
4984/* popen that works from a GUI.
4985 *
4986 * The result of this function is a pipe (file) connected to the
4987 * processes stdin or stdout, depending on the requested mode.
4988 */
4989
4990static PyObject *
4991posix_popen(PyObject *self, PyObject *args)
4992{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004993 PyObject *f;
4994 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004995
Victor Stinnerd6f85422010-05-05 23:33:33 +00004996 char *cmdstring;
4997 char *mode = "r";
4998 int bufsize = -1;
4999 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
5000 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005001
Victor Stinnerd6f85422010-05-05 23:33:33 +00005002 if (*mode == 'r')
5003 tm = _O_RDONLY;
5004 else if (*mode != 'w') {
5005 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
5006 return NULL;
5007 } else
5008 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00005009
Victor Stinnerd6f85422010-05-05 23:33:33 +00005010 if (bufsize != -1) {
5011 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
5012 return NULL;
5013 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005014
Victor Stinnerd6f85422010-05-05 23:33:33 +00005015 if (*(mode+1) == 't')
5016 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
5017 else if (*(mode+1) == 'b')
5018 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
5019 else
5020 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005021
Victor Stinnerd6f85422010-05-05 23:33:33 +00005022 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005023}
5024
5025/* Variation on win32pipe.popen
5026 *
5027 * The result of this function is a pipe (file) connected to the
5028 * process's stdin, and a pipe connected to the process's stdout.
5029 */
5030
5031static PyObject *
5032win32_popen2(PyObject *self, PyObject *args)
5033{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005034 PyObject *f;
5035 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00005036
Victor Stinnerd6f85422010-05-05 23:33:33 +00005037 char *cmdstring;
5038 char *mode = "t";
5039 int bufsize = -1;
5040 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5041 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005042
Victor Stinnerd6f85422010-05-05 23:33:33 +00005043 if (*mode == 't')
5044 tm = _O_TEXT;
5045 else if (*mode != 'b') {
5046 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5047 return NULL;
5048 } else
5049 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005050
Victor Stinnerd6f85422010-05-05 23:33:33 +00005051 if (bufsize != -1) {
5052 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5053 return NULL;
5054 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005055
Victor Stinnerd6f85422010-05-05 23:33:33 +00005056 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005057
Victor Stinnerd6f85422010-05-05 23:33:33 +00005058 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005059}
5060
5061/*
5062 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005063 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005064 * The result of this function is 3 pipes - the process's stdin,
5065 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005066 */
5067
5068static PyObject *
5069win32_popen3(PyObject *self, PyObject *args)
5070{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005071 PyObject *f;
5072 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005073
Victor Stinnerd6f85422010-05-05 23:33:33 +00005074 char *cmdstring;
5075 char *mode = "t";
5076 int bufsize = -1;
5077 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5078 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005079
Victor Stinnerd6f85422010-05-05 23:33:33 +00005080 if (*mode == 't')
5081 tm = _O_TEXT;
5082 else if (*mode != 'b') {
5083 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5084 return NULL;
5085 } else
5086 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005087
Victor Stinnerd6f85422010-05-05 23:33:33 +00005088 if (bufsize != -1) {
5089 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5090 return NULL;
5091 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005092
Victor Stinnerd6f85422010-05-05 23:33:33 +00005093 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005094
Victor Stinnerd6f85422010-05-05 23:33:33 +00005095 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005096}
5097
5098/*
5099 * Variation on win32pipe.popen
5100 *
Tim Peters5aa91602002-01-30 05:46:57 +00005101 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005102 * and stdout+stderr combined as a single pipe.
5103 */
5104
5105static PyObject *
5106win32_popen4(PyObject *self, PyObject *args)
5107{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005108 PyObject *f;
5109 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005110
Victor Stinnerd6f85422010-05-05 23:33:33 +00005111 char *cmdstring;
5112 char *mode = "t";
5113 int bufsize = -1;
5114 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5115 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005116
Victor Stinnerd6f85422010-05-05 23:33:33 +00005117 if (*mode == 't')
5118 tm = _O_TEXT;
5119 else if (*mode != 'b') {
5120 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5121 return NULL;
5122 } else
5123 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005124
Victor Stinnerd6f85422010-05-05 23:33:33 +00005125 if (bufsize != -1) {
5126 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5127 return NULL;
5128 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005129
Victor Stinnerd6f85422010-05-05 23:33:33 +00005130 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005131
Victor Stinnerd6f85422010-05-05 23:33:33 +00005132 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005133}
5134
Mark Hammond08501372001-01-31 07:30:29 +00005135static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005136_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005137 HANDLE hStdin,
5138 HANDLE hStdout,
5139 HANDLE hStderr,
5140 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005141{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005142 PROCESS_INFORMATION piProcInfo;
5143 STARTUPINFO siStartInfo;
5144 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5145 char *s1,*s2, *s3 = " /c ";
5146 const char *szConsoleSpawn = "w9xpopen.exe";
5147 int i;
5148 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005149
Victor Stinnerd6f85422010-05-05 23:33:33 +00005150 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5151 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005152
Victor Stinnerd6f85422010-05-05 23:33:33 +00005153 s1 = (char *)alloca(i);
5154 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5155 /* x < i, so x fits into an integer */
5156 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005157
Victor Stinnerd6f85422010-05-05 23:33:33 +00005158 /* Explicitly check if we are using COMMAND.COM. If we are
5159 * then use the w9xpopen hack.
5160 */
5161 comshell = s1 + x;
5162 while (comshell >= s1 && *comshell != '\\')
5163 --comshell;
5164 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005165
Victor Stinnerd6f85422010-05-05 23:33:33 +00005166 if (GetVersion() < 0x80000000 &&
5167 _stricmp(comshell, "command.com") != 0) {
5168 /* NT/2000 and not using command.com. */
5169 x = i + strlen(s3) + strlen(cmdstring) + 1;
5170 s2 = (char *)alloca(x);
5171 ZeroMemory(s2, x);
5172 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5173 }
5174 else {
5175 /*
5176 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5177 * the workaround listed in KB: Q150956
5178 */
5179 char modulepath[_MAX_PATH];
5180 struct stat statinfo;
5181 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5182 for (x = i = 0; modulepath[i]; i++)
5183 if (modulepath[i] == SEP)
5184 x = i+1;
5185 modulepath[x] = '\0';
5186 /* Create the full-name to w9xpopen, so we can test it exists */
5187 strncat(modulepath,
5188 szConsoleSpawn,
5189 (sizeof(modulepath)/sizeof(modulepath[0]))
5190 -strlen(modulepath));
5191 if (stat(modulepath, &statinfo) != 0) {
5192 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5193 /* Eeek - file-not-found - possibly an embedding
5194 situation - see if we can locate it in sys.prefix
5195 */
5196 strncpy(modulepath,
5197 Py_GetExecPrefix(),
5198 mplen);
5199 modulepath[mplen-1] = '\0';
5200 if (modulepath[strlen(modulepath)-1] != '\\')
5201 strcat(modulepath, "\\");
5202 strncat(modulepath,
5203 szConsoleSpawn,
5204 mplen-strlen(modulepath));
5205 /* No where else to look - raise an easily identifiable
5206 error, rather than leaving Windows to report
5207 "file not found" - as the user is probably blissfully
5208 unaware this shim EXE is used, and it will confuse them.
5209 (well, it confused me for a while ;-)
5210 */
5211 if (stat(modulepath, &statinfo) != 0) {
5212 PyErr_Format(PyExc_RuntimeError,
5213 "Can not locate '%s' which is needed "
5214 "for popen to work with your shell "
5215 "or platform.",
5216 szConsoleSpawn);
5217 return FALSE;
5218 }
5219 }
5220 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5221 strlen(modulepath) +
5222 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005223
Victor Stinnerd6f85422010-05-05 23:33:33 +00005224 s2 = (char *)alloca(x);
5225 ZeroMemory(s2, x);
5226 /* To maintain correct argument passing semantics,
5227 we pass the command-line as it stands, and allow
5228 quoting to be applied. w9xpopen.exe will then
5229 use its argv vector, and re-quote the necessary
5230 args for the ultimate child process.
5231 */
5232 PyOS_snprintf(
5233 s2, x,
5234 "\"%s\" %s%s%s",
5235 modulepath,
5236 s1,
5237 s3,
5238 cmdstring);
5239 /* Not passing CREATE_NEW_CONSOLE has been known to
5240 cause random failures on win9x. Specifically a
5241 dialog:
5242 "Your program accessed mem currently in use at xxx"
5243 and a hopeful warning about the stability of your
5244 system.
5245 Cost is Ctrl+C won't kill children, but anyone
5246 who cares can have a go!
5247 */
5248 dwProcessFlags |= CREATE_NEW_CONSOLE;
5249 }
5250 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005251
Victor Stinnerd6f85422010-05-05 23:33:33 +00005252 /* Could be an else here to try cmd.exe / command.com in the path
5253 Now we'll just error out.. */
5254 else {
5255 PyErr_SetString(PyExc_RuntimeError,
5256 "Cannot locate a COMSPEC environment variable to "
5257 "use as the shell");
5258 return FALSE;
5259 }
Tim Peters5aa91602002-01-30 05:46:57 +00005260
Victor Stinnerd6f85422010-05-05 23:33:33 +00005261 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5262 siStartInfo.cb = sizeof(STARTUPINFO);
5263 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5264 siStartInfo.hStdInput = hStdin;
5265 siStartInfo.hStdOutput = hStdout;
5266 siStartInfo.hStdError = hStderr;
5267 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005268
Victor Stinnerd6f85422010-05-05 23:33:33 +00005269 if (CreateProcess(NULL,
5270 s2,
5271 NULL,
5272 NULL,
5273 TRUE,
5274 dwProcessFlags,
5275 NULL,
5276 NULL,
5277 &siStartInfo,
5278 &piProcInfo) ) {
5279 /* Close the handles now so anyone waiting is woken. */
5280 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005281
Victor Stinnerd6f85422010-05-05 23:33:33 +00005282 /* Return process handle */
5283 *hProcess = piProcInfo.hProcess;
5284 return TRUE;
5285 }
5286 win32_error("CreateProcess", s2);
5287 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005288}
5289
5290/* The following code is based off of KB: Q190351 */
5291
5292static PyObject *
5293_PyPopen(char *cmdstring, int mode, int n)
5294{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005295 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5296 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5297 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005298
Victor Stinnerd6f85422010-05-05 23:33:33 +00005299 SECURITY_ATTRIBUTES saAttr;
5300 BOOL fSuccess;
5301 int fd1, fd2, fd3;
5302 FILE *f1, *f2, *f3;
5303 long file_count;
5304 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005305
Victor Stinnerd6f85422010-05-05 23:33:33 +00005306 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5307 saAttr.bInheritHandle = TRUE;
5308 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005309
Victor Stinnerd6f85422010-05-05 23:33:33 +00005310 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5311 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005312
Victor Stinnerd6f85422010-05-05 23:33:33 +00005313 /* Create new output read handle and the input write handle. Set
5314 * the inheritance properties to FALSE. Otherwise, the child inherits
5315 * these handles; resulting in non-closeable handles to the pipes
5316 * being created. */
5317 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5318 GetCurrentProcess(), &hChildStdinWrDup, 0,
5319 FALSE,
5320 DUPLICATE_SAME_ACCESS);
5321 if (!fSuccess)
5322 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005323
Victor Stinnerd6f85422010-05-05 23:33:33 +00005324 /* Close the inheritable version of ChildStdin
5325 that we're using. */
5326 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005327
Victor Stinnerd6f85422010-05-05 23:33:33 +00005328 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5329 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005330
Victor Stinnerd6f85422010-05-05 23:33:33 +00005331 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5332 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5333 FALSE, DUPLICATE_SAME_ACCESS);
5334 if (!fSuccess)
5335 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005336
Victor Stinnerd6f85422010-05-05 23:33:33 +00005337 /* Close the inheritable version of ChildStdout
5338 that we're using. */
5339 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005340
Victor Stinnerd6f85422010-05-05 23:33:33 +00005341 if (n != POPEN_4) {
5342 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5343 return win32_error("CreatePipe", NULL);
5344 fSuccess = DuplicateHandle(GetCurrentProcess(),
5345 hChildStderrRd,
5346 GetCurrentProcess(),
5347 &hChildStderrRdDup, 0,
5348 FALSE, DUPLICATE_SAME_ACCESS);
5349 if (!fSuccess)
5350 return win32_error("DuplicateHandle", NULL);
5351 /* Close the inheritable version of ChildStdErr that we're using. */
5352 CloseHandle(hChildStderrRd);
5353 }
Tim Peters5aa91602002-01-30 05:46:57 +00005354
Victor Stinnerd6f85422010-05-05 23:33:33 +00005355 switch (n) {
5356 case POPEN_1:
5357 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5358 case _O_WRONLY | _O_TEXT:
5359 /* Case for writing to child Stdin in text mode. */
5360 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5361 f1 = _fdopen(fd1, "w");
5362 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5363 PyFile_SetBufSize(f, 0);
5364 /* We don't care about these pipes anymore, so close them. */
5365 CloseHandle(hChildStdoutRdDup);
5366 CloseHandle(hChildStderrRdDup);
5367 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005368
Victor Stinnerd6f85422010-05-05 23:33:33 +00005369 case _O_RDONLY | _O_TEXT:
5370 /* Case for reading from child Stdout in text mode. */
5371 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5372 f1 = _fdopen(fd1, "r");
5373 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5374 PyFile_SetBufSize(f, 0);
5375 /* We don't care about these pipes anymore, so close them. */
5376 CloseHandle(hChildStdinWrDup);
5377 CloseHandle(hChildStderrRdDup);
5378 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005379
Victor Stinnerd6f85422010-05-05 23:33:33 +00005380 case _O_RDONLY | _O_BINARY:
5381 /* Case for readinig from child Stdout in binary mode. */
5382 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5383 f1 = _fdopen(fd1, "rb");
5384 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5385 PyFile_SetBufSize(f, 0);
5386 /* We don't care about these pipes anymore, so close them. */
5387 CloseHandle(hChildStdinWrDup);
5388 CloseHandle(hChildStderrRdDup);
5389 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005390
Victor Stinnerd6f85422010-05-05 23:33:33 +00005391 case _O_WRONLY | _O_BINARY:
5392 /* Case for writing to child Stdin in binary mode. */
5393 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5394 f1 = _fdopen(fd1, "wb");
5395 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5396 PyFile_SetBufSize(f, 0);
5397 /* We don't care about these pipes anymore, so close them. */
5398 CloseHandle(hChildStdoutRdDup);
5399 CloseHandle(hChildStderrRdDup);
5400 break;
5401 }
5402 file_count = 1;
5403 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005404
Victor Stinnerd6f85422010-05-05 23:33:33 +00005405 case POPEN_2:
5406 case POPEN_4:
5407 {
5408 char *m1, *m2;
5409 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005410
Victor Stinnerd6f85422010-05-05 23:33:33 +00005411 if (mode & _O_TEXT) {
5412 m1 = "r";
5413 m2 = "w";
5414 } else {
5415 m1 = "rb";
5416 m2 = "wb";
5417 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005418
Victor Stinnerd6f85422010-05-05 23:33:33 +00005419 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5420 f1 = _fdopen(fd1, m2);
5421 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5422 f2 = _fdopen(fd2, m1);
5423 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5424 PyFile_SetBufSize(p1, 0);
5425 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5426 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005427
Victor Stinnerd6f85422010-05-05 23:33:33 +00005428 if (n != 4)
5429 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005430
Victor Stinnerd6f85422010-05-05 23:33:33 +00005431 f = PyTuple_Pack(2,p1,p2);
5432 Py_XDECREF(p1);
5433 Py_XDECREF(p2);
5434 file_count = 2;
5435 break;
5436 }
Tim Peters5aa91602002-01-30 05:46:57 +00005437
Victor Stinnerd6f85422010-05-05 23:33:33 +00005438 case POPEN_3:
5439 {
5440 char *m1, *m2;
5441 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005442
Victor Stinnerd6f85422010-05-05 23:33:33 +00005443 if (mode & _O_TEXT) {
5444 m1 = "r";
5445 m2 = "w";
5446 } else {
5447 m1 = "rb";
5448 m2 = "wb";
5449 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005450
Victor Stinnerd6f85422010-05-05 23:33:33 +00005451 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5452 f1 = _fdopen(fd1, m2);
5453 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5454 f2 = _fdopen(fd2, m1);
5455 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5456 f3 = _fdopen(fd3, m1);
5457 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5458 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5459 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5460 PyFile_SetBufSize(p1, 0);
5461 PyFile_SetBufSize(p2, 0);
5462 PyFile_SetBufSize(p3, 0);
5463 f = PyTuple_Pack(3,p1,p2,p3);
5464 Py_XDECREF(p1);
5465 Py_XDECREF(p2);
5466 Py_XDECREF(p3);
5467 file_count = 3;
5468 break;
5469 }
5470 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005471
Victor Stinnerd6f85422010-05-05 23:33:33 +00005472 if (n == POPEN_4) {
5473 if (!_PyPopenCreateProcess(cmdstring,
5474 hChildStdinRd,
5475 hChildStdoutWr,
5476 hChildStdoutWr,
5477 &hProcess))
5478 return NULL;
5479 }
5480 else {
5481 if (!_PyPopenCreateProcess(cmdstring,
5482 hChildStdinRd,
5483 hChildStdoutWr,
5484 hChildStderrWr,
5485 &hProcess))
5486 return NULL;
5487 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005488
Victor Stinnerd6f85422010-05-05 23:33:33 +00005489 /*
5490 * Insert the files we've created into the process dictionary
5491 * all referencing the list with the process handle and the
5492 * initial number of files (see description below in _PyPclose).
5493 * Since if _PyPclose later tried to wait on a process when all
5494 * handles weren't closed, it could create a deadlock with the
5495 * child, we spend some energy here to try to ensure that we
5496 * either insert all file handles into the dictionary or none
5497 * at all. It's a little clumsy with the various popen modes
5498 * and variable number of files involved.
5499 */
5500 if (!_PyPopenProcs) {
5501 _PyPopenProcs = PyDict_New();
5502 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005503
Victor Stinnerd6f85422010-05-05 23:33:33 +00005504 if (_PyPopenProcs) {
5505 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5506 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005507
Victor Stinnerd6f85422010-05-05 23:33:33 +00005508 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5509 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005510
Victor Stinnerd6f85422010-05-05 23:33:33 +00005511 procObj = PyList_New(2);
5512 hProcessObj = PyLong_FromVoidPtr(hProcess);
5513 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005514
Victor Stinnerd6f85422010-05-05 23:33:33 +00005515 if (procObj && hProcessObj && intObj) {
5516 PyList_SetItem(procObj,0,hProcessObj);
5517 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005518
Victor Stinnerd6f85422010-05-05 23:33:33 +00005519 fileObj[0] = PyLong_FromVoidPtr(f1);
5520 if (fileObj[0]) {
5521 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5522 fileObj[0],
5523 procObj);
5524 }
5525 if (file_count >= 2) {
5526 fileObj[1] = PyLong_FromVoidPtr(f2);
5527 if (fileObj[1]) {
5528 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5529 fileObj[1],
5530 procObj);
5531 }
5532 }
5533 if (file_count >= 3) {
5534 fileObj[2] = PyLong_FromVoidPtr(f3);
5535 if (fileObj[2]) {
5536 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5537 fileObj[2],
5538 procObj);
5539 }
5540 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005541
Victor Stinnerd6f85422010-05-05 23:33:33 +00005542 if (ins_rc[0] < 0 || !fileObj[0] ||
5543 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5544 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5545 /* Something failed - remove any dictionary
5546 * entries that did make it.
5547 */
5548 if (!ins_rc[0] && fileObj[0]) {
5549 PyDict_DelItem(_PyPopenProcs,
5550 fileObj[0]);
5551 }
5552 if (!ins_rc[1] && fileObj[1]) {
5553 PyDict_DelItem(_PyPopenProcs,
5554 fileObj[1]);
5555 }
5556 if (!ins_rc[2] && fileObj[2]) {
5557 PyDict_DelItem(_PyPopenProcs,
5558 fileObj[2]);
5559 }
5560 }
5561 }
Tim Peters5aa91602002-01-30 05:46:57 +00005562
Victor Stinnerd6f85422010-05-05 23:33:33 +00005563 /*
5564 * Clean up our localized references for the dictionary keys
5565 * and value since PyDict_SetItem will Py_INCREF any copies
5566 * that got placed in the dictionary.
5567 */
5568 Py_XDECREF(procObj);
5569 Py_XDECREF(fileObj[0]);
5570 Py_XDECREF(fileObj[1]);
5571 Py_XDECREF(fileObj[2]);
5572 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005573
Victor Stinnerd6f85422010-05-05 23:33:33 +00005574 /* Child is launched. Close the parents copy of those pipe
5575 * handles that only the child should have open. You need to
5576 * make sure that no handles to the write end of the output pipe
5577 * are maintained in this process or else the pipe will not close
5578 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005579
Victor Stinnerd6f85422010-05-05 23:33:33 +00005580 if (!CloseHandle(hChildStdinRd))
5581 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005582
Victor Stinnerd6f85422010-05-05 23:33:33 +00005583 if (!CloseHandle(hChildStdoutWr))
5584 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005585
Victor Stinnerd6f85422010-05-05 23:33:33 +00005586 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5587 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005588
Victor Stinnerd6f85422010-05-05 23:33:33 +00005589 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005590}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005591
5592/*
5593 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5594 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005595 *
5596 * This function uses the _PyPopenProcs dictionary in order to map the
5597 * input file pointer to information about the process that was
5598 * originally created by the popen* call that created the file pointer.
5599 * The dictionary uses the file pointer as a key (with one entry
5600 * inserted for each file returned by the original popen* call) and a
5601 * single list object as the value for all files from a single call.
5602 * The list object contains the Win32 process handle at [0], and a file
5603 * count at [1], which is initialized to the total number of file
5604 * handles using that list.
5605 *
5606 * This function closes whichever handle it is passed, and decrements
5607 * the file count in the dictionary for the process handle pointed to
5608 * by this file. On the last close (when the file count reaches zero),
5609 * this function will wait for the child process and then return its
5610 * exit code as the result of the close() operation. This permits the
5611 * files to be closed in any order - it is always the close() of the
5612 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005613 *
5614 * NOTE: This function is currently called with the GIL released.
5615 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005616 */
Tim Peters736aa322000-09-01 06:51:24 +00005617
Fredrik Lundh56055a42000-07-23 19:47:12 +00005618static int _PyPclose(FILE *file)
5619{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005620 int result;
5621 DWORD exit_code;
5622 HANDLE hProcess;
5623 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5624 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005625#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005626 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005627#endif
5628
Victor Stinnerd6f85422010-05-05 23:33:33 +00005629 /* Close the file handle first, to ensure it can't block the
5630 * child from exiting if it's the last handle.
5631 */
5632 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005633#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005634 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005635#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005636 if (_PyPopenProcs) {
5637 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5638 (procObj = PyDict_GetItem(_PyPopenProcs,
5639 fileObj)) != NULL &&
5640 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5641 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005642
Victor Stinnerd6f85422010-05-05 23:33:33 +00005643 hProcess = PyLong_AsVoidPtr(hProcessObj);
5644 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005645
Victor Stinnerd6f85422010-05-05 23:33:33 +00005646 if (file_count > 1) {
5647 /* Still other files referencing process */
5648 file_count--;
5649 PyList_SetItem(procObj,1,
5650 PyInt_FromLong(file_count));
5651 } else {
5652 /* Last file for this process */
5653 if (result != EOF &&
5654 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5655 GetExitCodeProcess(hProcess, &exit_code)) {
5656 /* Possible truncation here in 16-bit environments, but
5657 * real exit codes are just the lower byte in any event.
5658 */
5659 result = exit_code;
5660 } else {
5661 /* Indicate failure - this will cause the file object
5662 * to raise an I/O error and translate the last Win32
5663 * error code from errno. We do have a problem with
5664 * last errors that overlap the normal errno table,
5665 * but that's a consistent problem with the file object.
5666 */
5667 if (result != EOF) {
5668 /* If the error wasn't from the fclose(), then
5669 * set errno for the file object error handling.
5670 */
5671 errno = GetLastError();
5672 }
5673 result = -1;
5674 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005675
Victor Stinnerd6f85422010-05-05 23:33:33 +00005676 /* Free up the native handle at this point */
5677 CloseHandle(hProcess);
5678 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005679
Victor Stinnerd6f85422010-05-05 23:33:33 +00005680 /* Remove this file pointer from dictionary */
5681 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005682
Victor Stinnerd6f85422010-05-05 23:33:33 +00005683 if (PyDict_Size(_PyPopenProcs) == 0) {
5684 Py_DECREF(_PyPopenProcs);
5685 _PyPopenProcs = NULL;
5686 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005687
Victor Stinnerd6f85422010-05-05 23:33:33 +00005688 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005689
Victor Stinnerd6f85422010-05-05 23:33:33 +00005690 Py_XDECREF(fileObj);
5691 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005692
Tim Peters736aa322000-09-01 06:51:24 +00005693#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005694 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005695#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005696 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005697}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005698
5699#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005701posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005702{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005703 char *name;
5704 char *mode = "r";
5705 int bufsize = -1;
5706 FILE *fp;
5707 PyObject *f;
5708 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5709 return NULL;
5710 /* Strip mode of binary or text modifiers */
5711 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5712 mode = "r";
5713 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5714 mode = "w";
5715 Py_BEGIN_ALLOW_THREADS
5716 fp = popen(name, mode);
5717 Py_END_ALLOW_THREADS
5718 if (fp == NULL)
5719 return posix_error();
5720 f = PyFile_FromFile(fp, name, mode, pclose);
5721 if (f != NULL)
5722 PyFile_SetBufSize(f, bufsize);
5723 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005724}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005725
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005726#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005727#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005728
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005729
Guido van Rossumb6775db1994-08-01 11:34:53 +00005730#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005731PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005732"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733Set the current process's user id.");
5734
Barry Warsaw53699e91996-12-10 23:23:01 +00005735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005736posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005737{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005738 long uid_arg;
5739 uid_t uid;
5740 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5741 return NULL;
5742 uid = uid_arg;
5743 if (uid != uid_arg) {
5744 PyErr_SetString(PyExc_OverflowError, "user id too big");
5745 return NULL;
5746 }
5747 if (setuid(uid) < 0)
5748 return posix_error();
5749 Py_INCREF(Py_None);
5750 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005751}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005752#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005754
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005755#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005756PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005757"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758Set the current process's effective user id.");
5759
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005760static PyObject *
5761posix_seteuid (PyObject *self, PyObject *args)
5762{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005763 long euid_arg;
5764 uid_t euid;
5765 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5766 return NULL;
5767 euid = euid_arg;
5768 if (euid != euid_arg) {
5769 PyErr_SetString(PyExc_OverflowError, "user id too big");
5770 return NULL;
5771 }
5772 if (seteuid(euid) < 0) {
5773 return posix_error();
5774 } else {
5775 Py_INCREF(Py_None);
5776 return Py_None;
5777 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005778}
5779#endif /* HAVE_SETEUID */
5780
5781#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005782PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005783"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005784Set the current process's effective group id.");
5785
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005786static PyObject *
5787posix_setegid (PyObject *self, PyObject *args)
5788{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005789 long egid_arg;
5790 gid_t egid;
5791 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5792 return NULL;
5793 egid = egid_arg;
5794 if (egid != egid_arg) {
5795 PyErr_SetString(PyExc_OverflowError, "group id too big");
5796 return NULL;
5797 }
5798 if (setegid(egid) < 0) {
5799 return posix_error();
5800 } else {
5801 Py_INCREF(Py_None);
5802 return Py_None;
5803 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005804}
5805#endif /* HAVE_SETEGID */
5806
5807#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005809"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005810Set the current process's real and effective user ids.");
5811
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005812static PyObject *
5813posix_setreuid (PyObject *self, PyObject *args)
5814{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005815 long ruid_arg, euid_arg;
5816 uid_t ruid, euid;
5817 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5818 return NULL;
5819 if (ruid_arg == -1)
5820 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5821 else
5822 ruid = ruid_arg; /* otherwise, assign from our long */
5823 if (euid_arg == -1)
5824 euid = (uid_t)-1;
5825 else
5826 euid = euid_arg;
5827 if ((euid_arg != -1 && euid != euid_arg) ||
5828 (ruid_arg != -1 && ruid != ruid_arg)) {
5829 PyErr_SetString(PyExc_OverflowError, "user id too big");
5830 return NULL;
5831 }
5832 if (setreuid(ruid, euid) < 0) {
5833 return posix_error();
5834 } else {
5835 Py_INCREF(Py_None);
5836 return Py_None;
5837 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005838}
5839#endif /* HAVE_SETREUID */
5840
5841#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005842PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005843"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844Set the current process's real and effective group ids.");
5845
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005846static PyObject *
5847posix_setregid (PyObject *self, PyObject *args)
5848{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005849 long rgid_arg, egid_arg;
5850 gid_t rgid, egid;
5851 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5852 return NULL;
5853 if (rgid_arg == -1)
5854 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5855 else
5856 rgid = rgid_arg; /* otherwise, assign from our long */
5857 if (egid_arg == -1)
5858 egid = (gid_t)-1;
5859 else
5860 egid = egid_arg;
5861 if ((egid_arg != -1 && egid != egid_arg) ||
5862 (rgid_arg != -1 && rgid != rgid_arg)) {
5863 PyErr_SetString(PyExc_OverflowError, "group id too big");
5864 return NULL;
5865 }
5866 if (setregid(rgid, egid) < 0) {
5867 return posix_error();
5868 } else {
5869 Py_INCREF(Py_None);
5870 return Py_None;
5871 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005872}
5873#endif /* HAVE_SETREGID */
5874
Guido van Rossumb6775db1994-08-01 11:34:53 +00005875#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005876PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005877"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005879
Barry Warsaw53699e91996-12-10 23:23:01 +00005880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005881posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005882{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005883 long gid_arg;
5884 gid_t gid;
5885 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5886 return NULL;
5887 gid = gid_arg;
5888 if (gid != gid_arg) {
5889 PyErr_SetString(PyExc_OverflowError, "group id too big");
5890 return NULL;
5891 }
5892 if (setgid(gid) < 0)
5893 return posix_error();
5894 Py_INCREF(Py_None);
5895 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005896}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005897#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005898
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005899#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005900PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005901"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005902Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005903
5904static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005905posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005906{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005907 int i, len;
5908 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005909
Victor Stinnerd6f85422010-05-05 23:33:33 +00005910 if (!PySequence_Check(groups)) {
5911 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5912 return NULL;
5913 }
5914 len = PySequence_Size(groups);
5915 if (len > MAX_GROUPS) {
5916 PyErr_SetString(PyExc_ValueError, "too many groups");
5917 return NULL;
5918 }
5919 for(i = 0; i < len; i++) {
5920 PyObject *elem;
5921 elem = PySequence_GetItem(groups, i);
5922 if (!elem)
5923 return NULL;
5924 if (!PyInt_Check(elem)) {
5925 if (!PyLong_Check(elem)) {
5926 PyErr_SetString(PyExc_TypeError,
5927 "groups must be integers");
5928 Py_DECREF(elem);
5929 return NULL;
5930 } else {
5931 unsigned long x = PyLong_AsUnsignedLong(elem);
5932 if (PyErr_Occurred()) {
5933 PyErr_SetString(PyExc_TypeError,
5934 "group id too big");
5935 Py_DECREF(elem);
5936 return NULL;
5937 }
5938 grouplist[i] = x;
5939 /* read back to see if it fits in gid_t */
5940 if (grouplist[i] != x) {
5941 PyErr_SetString(PyExc_TypeError,
5942 "group id too big");
5943 Py_DECREF(elem);
5944 return NULL;
5945 }
5946 }
5947 } else {
5948 long x = PyInt_AsLong(elem);
5949 grouplist[i] = x;
5950 if (grouplist[i] != x) {
5951 PyErr_SetString(PyExc_TypeError,
5952 "group id too big");
5953 Py_DECREF(elem);
5954 return NULL;
5955 }
5956 }
5957 Py_DECREF(elem);
5958 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005959
Victor Stinnerd6f85422010-05-05 23:33:33 +00005960 if (setgroups(len, grouplist) < 0)
5961 return posix_error();
5962 Py_INCREF(Py_None);
5963 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005964}
5965#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005966
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005967#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005968static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005969wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005970{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005971 PyObject *result;
5972 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005973
Victor Stinnerd6f85422010-05-05 23:33:33 +00005974 if (pid == -1)
5975 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005976
Victor Stinnerd6f85422010-05-05 23:33:33 +00005977 if (struct_rusage == NULL) {
5978 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5979 if (m == NULL)
5980 return NULL;
5981 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5982 Py_DECREF(m);
5983 if (struct_rusage == NULL)
5984 return NULL;
5985 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005986
Victor Stinnerd6f85422010-05-05 23:33:33 +00005987 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5988 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5989 if (!result)
5990 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005991
5992#ifndef doubletime
5993#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5994#endif
5995
Victor Stinnerd6f85422010-05-05 23:33:33 +00005996 PyStructSequence_SET_ITEM(result, 0,
5997 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5998 PyStructSequence_SET_ITEM(result, 1,
5999 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00006000#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00006001 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
6002 SET_INT(result, 2, ru->ru_maxrss);
6003 SET_INT(result, 3, ru->ru_ixrss);
6004 SET_INT(result, 4, ru->ru_idrss);
6005 SET_INT(result, 5, ru->ru_isrss);
6006 SET_INT(result, 6, ru->ru_minflt);
6007 SET_INT(result, 7, ru->ru_majflt);
6008 SET_INT(result, 8, ru->ru_nswap);
6009 SET_INT(result, 9, ru->ru_inblock);
6010 SET_INT(result, 10, ru->ru_oublock);
6011 SET_INT(result, 11, ru->ru_msgsnd);
6012 SET_INT(result, 12, ru->ru_msgrcv);
6013 SET_INT(result, 13, ru->ru_nsignals);
6014 SET_INT(result, 14, ru->ru_nvcsw);
6015 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00006016#undef SET_INT
6017
Victor Stinnerd6f85422010-05-05 23:33:33 +00006018 if (PyErr_Occurred()) {
6019 Py_DECREF(result);
6020 return NULL;
6021 }
Neal Norwitz05a45592006-03-20 06:30:08 +00006022
Victor Stinnerd6f85422010-05-05 23:33:33 +00006023 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00006024}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00006025#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00006026
6027#ifdef HAVE_WAIT3
6028PyDoc_STRVAR(posix_wait3__doc__,
6029"wait3(options) -> (pid, status, rusage)\n\n\
6030Wait for completion of a child process.");
6031
6032static PyObject *
6033posix_wait3(PyObject *self, PyObject *args)
6034{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006035 pid_t pid;
6036 int options;
6037 struct rusage ru;
6038 WAIT_TYPE status;
6039 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006040
Victor Stinnerd6f85422010-05-05 23:33:33 +00006041 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6042 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006043
Victor Stinnerd6f85422010-05-05 23:33:33 +00006044 Py_BEGIN_ALLOW_THREADS
6045 pid = wait3(&status, options, &ru);
6046 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006047
Victor Stinnerd6f85422010-05-05 23:33:33 +00006048 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006049}
6050#endif /* HAVE_WAIT3 */
6051
6052#ifdef HAVE_WAIT4
6053PyDoc_STRVAR(posix_wait4__doc__,
6054"wait4(pid, options) -> (pid, status, rusage)\n\n\
6055Wait for completion of a given child process.");
6056
6057static PyObject *
6058posix_wait4(PyObject *self, PyObject *args)
6059{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006060 pid_t pid;
6061 int options;
6062 struct rusage ru;
6063 WAIT_TYPE status;
6064 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006065
Victor Stinnerd6f85422010-05-05 23:33:33 +00006066 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6067 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006068
Victor Stinnerd6f85422010-05-05 23:33:33 +00006069 Py_BEGIN_ALLOW_THREADS
6070 pid = wait4(pid, &status, options, &ru);
6071 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006072
Victor Stinnerd6f85422010-05-05 23:33:33 +00006073 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006074}
6075#endif /* HAVE_WAIT4 */
6076
Guido van Rossumb6775db1994-08-01 11:34:53 +00006077#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006081
Barry Warsaw53699e91996-12-10 23:23:01 +00006082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006084{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006085 pid_t pid;
6086 int options;
6087 WAIT_TYPE status;
6088 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006089
Victor Stinnerd6f85422010-05-05 23:33:33 +00006090 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6091 return NULL;
6092 Py_BEGIN_ALLOW_THREADS
6093 pid = waitpid(pid, &status, options);
6094 Py_END_ALLOW_THREADS
6095 if (pid == -1)
6096 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006097
Victor Stinnerd6f85422010-05-05 23:33:33 +00006098 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006099}
6100
Tim Petersab034fa2002-02-01 11:27:43 +00006101#elif defined(HAVE_CWAIT)
6102
6103/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006104PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006105"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006107
6108static PyObject *
6109posix_waitpid(PyObject *self, PyObject *args)
6110{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006111 Py_intptr_t pid;
6112 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006113
Victor Stinnerd6f85422010-05-05 23:33:33 +00006114 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6115 return NULL;
6116 Py_BEGIN_ALLOW_THREADS
6117 pid = _cwait(&status, pid, options);
6118 Py_END_ALLOW_THREADS
6119 if (pid == -1)
6120 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006121
Victor Stinnerd6f85422010-05-05 23:33:33 +00006122 /* shift the status left a byte so this is more like the POSIX waitpid */
6123 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006124}
6125#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006126
Guido van Rossumad0ee831995-03-01 10:34:45 +00006127#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006129"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006131
Barry Warsaw53699e91996-12-10 23:23:01 +00006132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006133posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006134{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006135 pid_t pid;
6136 WAIT_TYPE status;
6137 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006138
Victor Stinnerd6f85422010-05-05 23:33:33 +00006139 Py_BEGIN_ALLOW_THREADS
6140 pid = wait(&status);
6141 Py_END_ALLOW_THREADS
6142 if (pid == -1)
6143 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006144
Victor Stinnerd6f85422010-05-05 23:33:33 +00006145 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006146}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006147#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006149
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006150PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006151"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006152Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006153
Barry Warsaw53699e91996-12-10 23:23:01 +00006154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006155posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006156{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006157#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006158 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006159#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006160#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006161 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006162#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006163 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006164#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006165#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006166}
6167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006168
Guido van Rossumb6775db1994-08-01 11:34:53 +00006169#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006170PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006171"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006173
Barry Warsaw53699e91996-12-10 23:23:01 +00006174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006175posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006176{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006177 PyObject* v;
6178 char buf[MAXPATHLEN];
6179 char *path;
6180 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006181#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006182 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006183#endif
6184
Victor Stinnerd6f85422010-05-05 23:33:33 +00006185 if (!PyArg_ParseTuple(args, "et:readlink",
6186 Py_FileSystemDefaultEncoding, &path))
6187 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006188#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006189 v = PySequence_GetItem(args, 0);
6190 if (v == NULL) {
6191 PyMem_Free(path);
6192 return NULL;
6193 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006194
Victor Stinnerd6f85422010-05-05 23:33:33 +00006195 if (PyUnicode_Check(v)) {
6196 arg_is_unicode = 1;
6197 }
6198 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006199#endif
6200
Victor Stinnerd6f85422010-05-05 23:33:33 +00006201 Py_BEGIN_ALLOW_THREADS
6202 n = readlink(path, buf, (int) sizeof buf);
6203 Py_END_ALLOW_THREADS
6204 if (n < 0)
6205 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006206
Victor Stinnerd6f85422010-05-05 23:33:33 +00006207 PyMem_Free(path);
6208 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006209#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006210 if (arg_is_unicode) {
6211 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006212
Victor Stinnerd6f85422010-05-05 23:33:33 +00006213 w = PyUnicode_FromEncodedObject(v,
6214 Py_FileSystemDefaultEncoding,
6215 "strict");
6216 if (w != NULL) {
6217 Py_DECREF(v);
6218 v = w;
6219 }
6220 else {
6221 /* fall back to the original byte string, as
6222 discussed in patch #683592 */
6223 PyErr_Clear();
6224 }
6225 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006226#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006227 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006228}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006229#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006231
Guido van Rossumb6775db1994-08-01 11:34:53 +00006232#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006233PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006234"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006235Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006236
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006238posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006239{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006240 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006241}
6242#endif /* HAVE_SYMLINK */
6243
6244
6245#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006246#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6247static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006248system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006249{
6250 ULONG value = 0;
6251
6252 Py_BEGIN_ALLOW_THREADS
6253 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6254 Py_END_ALLOW_THREADS
6255
6256 return value;
6257}
6258
6259static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006260posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006261{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006262 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006263 return Py_BuildValue("ddddd",
6264 (double)0 /* t.tms_utime / HZ */,
6265 (double)0 /* t.tms_stime / HZ */,
6266 (double)0 /* t.tms_cutime / HZ */,
6267 (double)0 /* t.tms_cstime / HZ */,
6268 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006269}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006270#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006271#define NEED_TICKS_PER_SECOND
6272static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006273static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006274posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006275{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006276 struct tms t;
6277 clock_t c;
6278 errno = 0;
6279 c = times(&t);
6280 if (c == (clock_t) -1)
6281 return posix_error();
6282 return Py_BuildValue("ddddd",
6283 (double)t.tms_utime / ticks_per_second,
6284 (double)t.tms_stime / ticks_per_second,
6285 (double)t.tms_cutime / ticks_per_second,
6286 (double)t.tms_cstime / ticks_per_second,
6287 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006288}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006289#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006290#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006291
6292
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006293#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006294#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006295static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006296posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006297{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006298 FILETIME create, exit, kernel, user;
6299 HANDLE hProc;
6300 hProc = GetCurrentProcess();
6301 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6302 /* The fields of a FILETIME structure are the hi and lo part
6303 of a 64-bit value expressed in 100 nanosecond units.
6304 1e7 is one second in such units; 1e-7 the inverse.
6305 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6306 */
6307 return Py_BuildValue(
6308 "ddddd",
6309 (double)(user.dwHighDateTime*429.4967296 +
6310 user.dwLowDateTime*1e-7),
6311 (double)(kernel.dwHighDateTime*429.4967296 +
6312 kernel.dwLowDateTime*1e-7),
6313 (double)0,
6314 (double)0,
6315 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006316}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006317#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006318
6319#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006321"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006322Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006323#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006325
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006326#ifdef HAVE_GETSID
6327PyDoc_STRVAR(posix_getsid__doc__,
6328"getsid(pid) -> sid\n\n\
6329Call the system call getsid().");
6330
6331static PyObject *
6332posix_getsid(PyObject *self, PyObject *args)
6333{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006334 pid_t pid;
6335 int sid;
6336 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6337 return NULL;
6338 sid = getsid(pid);
6339 if (sid < 0)
6340 return posix_error();
6341 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006342}
6343#endif /* HAVE_GETSID */
6344
6345
Guido van Rossumb6775db1994-08-01 11:34:53 +00006346#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006348"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006349Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006350
Barry Warsaw53699e91996-12-10 23:23:01 +00006351static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006352posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006353{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006354 if (setsid() < 0)
6355 return posix_error();
6356 Py_INCREF(Py_None);
6357 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006358}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006359#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006360
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006363"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006365
Barry Warsaw53699e91996-12-10 23:23:01 +00006366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006367posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006368{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006369 pid_t pid;
6370 int pgrp;
6371 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6372 return NULL;
6373 if (setpgid(pid, pgrp) < 0)
6374 return posix_error();
6375 Py_INCREF(Py_None);
6376 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006377}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006378#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006380
Guido van Rossumb6775db1994-08-01 11:34:53 +00006381#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006382PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006383"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006384Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006385
Barry Warsaw53699e91996-12-10 23:23:01 +00006386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006387posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006388{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006389 int fd;
6390 pid_t pgid;
6391 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6392 return NULL;
6393 pgid = tcgetpgrp(fd);
6394 if (pgid < 0)
6395 return posix_error();
6396 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006397}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006398#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006400
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006403"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006405
Barry Warsaw53699e91996-12-10 23:23:01 +00006406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006407posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006408{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006409 int fd;
6410 pid_t pgid;
6411 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6412 return NULL;
6413 if (tcsetpgrp(fd, pgid) < 0)
6414 return posix_error();
6415 Py_INCREF(Py_None);
6416 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006417}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006418#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006419
Guido van Rossum687dd131993-05-17 08:34:16 +00006420/* Functions acting on file descriptors */
6421
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006423"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006424Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006425
Barry Warsaw53699e91996-12-10 23:23:01 +00006426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006427posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006428{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006429 char *file = NULL;
6430 int flag;
6431 int mode = 0777;
6432 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006433
6434#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006435 PyUnicodeObject *po;
6436 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6437 Py_BEGIN_ALLOW_THREADS
6438 /* PyUnicode_AS_UNICODE OK without thread
6439 lock as it is a simple dereference. */
6440 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6441 Py_END_ALLOW_THREADS
6442 if (fd < 0)
6443 return posix_error();
6444 return PyInt_FromLong((long)fd);
6445 }
6446 /* Drop the argument parsing error as narrow strings
6447 are also valid. */
6448 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006449#endif
6450
Victor Stinnerd6f85422010-05-05 23:33:33 +00006451 if (!PyArg_ParseTuple(args, "eti|i",
6452 Py_FileSystemDefaultEncoding, &file,
6453 &flag, &mode))
6454 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006455
Victor Stinnerd6f85422010-05-05 23:33:33 +00006456 Py_BEGIN_ALLOW_THREADS
6457 fd = open(file, flag, mode);
6458 Py_END_ALLOW_THREADS
6459 if (fd < 0)
6460 return posix_error_with_allocated_filename(file);
6461 PyMem_Free(file);
6462 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006463}
6464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006466PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006467"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006468Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006469
Barry Warsaw53699e91996-12-10 23:23:01 +00006470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006471posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006472{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006473 int fd, res;
6474 if (!PyArg_ParseTuple(args, "i:close", &fd))
6475 return NULL;
6476 if (!_PyVerify_fd(fd))
6477 return posix_error();
6478 Py_BEGIN_ALLOW_THREADS
6479 res = close(fd);
6480 Py_END_ALLOW_THREADS
6481 if (res < 0)
6482 return posix_error();
6483 Py_INCREF(Py_None);
6484 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006485}
6486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006487
Victor Stinnerd6f85422010-05-05 23:33:33 +00006488PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006489"closerange(fd_low, fd_high)\n\n\
6490Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6491
6492static PyObject *
6493posix_closerange(PyObject *self, PyObject *args)
6494{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006495 int fd_from, fd_to, i;
6496 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6497 return NULL;
6498 Py_BEGIN_ALLOW_THREADS
6499 for (i = fd_from; i < fd_to; i++)
6500 if (_PyVerify_fd(i))
6501 close(i);
6502 Py_END_ALLOW_THREADS
6503 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006504}
6505
6506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006507PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006508"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006509Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006510
Barry Warsaw53699e91996-12-10 23:23:01 +00006511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006512posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006513{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006514 int fd;
6515 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6516 return NULL;
6517 if (!_PyVerify_fd(fd))
6518 return posix_error();
6519 Py_BEGIN_ALLOW_THREADS
6520 fd = dup(fd);
6521 Py_END_ALLOW_THREADS
6522 if (fd < 0)
6523 return posix_error();
6524 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006525}
6526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006529"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006531
Barry Warsaw53699e91996-12-10 23:23:01 +00006532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006533posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006534{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006535 int fd, fd2, res;
6536 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6537 return NULL;
6538 if (!_PyVerify_fd_dup2(fd, fd2))
6539 return posix_error();
6540 Py_BEGIN_ALLOW_THREADS
6541 res = dup2(fd, fd2);
6542 Py_END_ALLOW_THREADS
6543 if (res < 0)
6544 return posix_error();
6545 Py_INCREF(Py_None);
6546 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006547}
6548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006549
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006551"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006552Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006553
Barry Warsaw53699e91996-12-10 23:23:01 +00006554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006555posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006556{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006557 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006558#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006559 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006560#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006561 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006562#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006563 PyObject *posobj;
6564 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6565 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006566#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006567 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6568 switch (how) {
6569 case 0: how = SEEK_SET; break;
6570 case 1: how = SEEK_CUR; break;
6571 case 2: how = SEEK_END; break;
6572 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006573#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006574
6575#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006576 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006577#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006578 pos = PyLong_Check(posobj) ?
6579 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006580#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006581 if (PyErr_Occurred())
6582 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006583
Victor Stinnerd6f85422010-05-05 23:33:33 +00006584 if (!_PyVerify_fd(fd))
6585 return posix_error();
6586 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006587#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006588 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006589#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006590 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006591#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006592 Py_END_ALLOW_THREADS
6593 if (res < 0)
6594 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006595
6596#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006597 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006598#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006599 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006600#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006601}
6602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006604PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006605"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006606Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006607
Barry Warsaw53699e91996-12-10 23:23:01 +00006608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006609posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006610{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006611 int fd, size, n;
6612 PyObject *buffer;
6613 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6614 return NULL;
6615 if (size < 0) {
6616 errno = EINVAL;
6617 return posix_error();
6618 }
6619 buffer = PyString_FromStringAndSize((char *)NULL, size);
6620 if (buffer == NULL)
6621 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006622 if (!_PyVerify_fd(fd)) {
6623 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006624 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006625 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006626 Py_BEGIN_ALLOW_THREADS
6627 n = read(fd, PyString_AsString(buffer), size);
6628 Py_END_ALLOW_THREADS
6629 if (n < 0) {
6630 Py_DECREF(buffer);
6631 return posix_error();
6632 }
6633 if (n != size)
6634 _PyString_Resize(&buffer, n);
6635 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006636}
6637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006638
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006639PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006640"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006641Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006642
Barry Warsaw53699e91996-12-10 23:23:01 +00006643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006644posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006645{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006646 Py_buffer pbuf;
6647 int fd;
6648 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006649
Victor Stinnerd6f85422010-05-05 23:33:33 +00006650 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6651 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006652 if (!_PyVerify_fd(fd)) {
6653 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006654 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006655 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006656 Py_BEGIN_ALLOW_THREADS
6657 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6658 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006659 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006660 if (size < 0)
6661 return posix_error();
6662 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006663}
6664
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006665
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006666PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006667"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006669
Barry Warsaw53699e91996-12-10 23:23:01 +00006670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006671posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006672{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006673 int fd;
6674 STRUCT_STAT st;
6675 int res;
6676 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6677 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006678#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006679 /* on OpenVMS we must ensure that all bytes are written to the file */
6680 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006681#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006682 if (!_PyVerify_fd(fd))
6683 return posix_error();
6684 Py_BEGIN_ALLOW_THREADS
6685 res = FSTAT(fd, &st);
6686 Py_END_ALLOW_THREADS
6687 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006688#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006689 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006690#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006691 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006692#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006693 }
Tim Peters5aa91602002-01-30 05:46:57 +00006694
Victor Stinnerd6f85422010-05-05 23:33:33 +00006695 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006696}
6697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006698
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006700"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006701Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006702
Barry Warsaw53699e91996-12-10 23:23:01 +00006703static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006704posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006705{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006706 int fd;
6707 char *orgmode = "r";
6708 int bufsize = -1;
6709 FILE *fp;
6710 PyObject *f;
6711 char *mode;
6712 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6713 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006714
Victor Stinnerd6f85422010-05-05 23:33:33 +00006715 /* Sanitize mode. See fileobject.c */
6716 mode = PyMem_MALLOC(strlen(orgmode)+3);
6717 if (!mode) {
6718 PyErr_NoMemory();
6719 return NULL;
6720 }
6721 strcpy(mode, orgmode);
6722 if (_PyFile_SanitizeMode(mode)) {
6723 PyMem_FREE(mode);
6724 return NULL;
6725 }
6726 if (!_PyVerify_fd(fd))
6727 return posix_error();
6728 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006729#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006730 if (mode[0] == 'a') {
6731 /* try to make sure the O_APPEND flag is set */
6732 int flags;
6733 flags = fcntl(fd, F_GETFL);
6734 if (flags != -1)
6735 fcntl(fd, F_SETFL, flags | O_APPEND);
6736 fp = fdopen(fd, mode);
6737 if (fp == NULL && flags != -1)
6738 /* restore old mode if fdopen failed */
6739 fcntl(fd, F_SETFL, flags);
6740 } else {
6741 fp = fdopen(fd, mode);
6742 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006743#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006744 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006745#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006746 Py_END_ALLOW_THREADS
6747 PyMem_FREE(mode);
6748 if (fp == NULL)
6749 return posix_error();
6750 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6751 if (f != NULL)
6752 PyFile_SetBufSize(f, bufsize);
6753 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006754}
6755
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006756PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006757"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006758Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006759connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006760
6761static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006762posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006763{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006764 int fd;
6765 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6766 return NULL;
6767 if (!_PyVerify_fd(fd))
6768 return PyBool_FromLong(0);
6769 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006770}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006771
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006772#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006773PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006774"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006775Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006776
Barry Warsaw53699e91996-12-10 23:23:01 +00006777static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006778posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006779{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006780#if defined(PYOS_OS2)
6781 HFILE read, write;
6782 APIRET rc;
6783
Victor Stinnerd6f85422010-05-05 23:33:33 +00006784 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006785 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006786 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006787 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006788 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006789
6790 return Py_BuildValue("(ii)", read, write);
6791#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006792#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006793 int fds[2];
6794 int res;
6795 Py_BEGIN_ALLOW_THREADS
6796 res = pipe(fds);
6797 Py_END_ALLOW_THREADS
6798 if (res != 0)
6799 return posix_error();
6800 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006801#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006802 HANDLE read, write;
6803 int read_fd, write_fd;
6804 BOOL ok;
6805 Py_BEGIN_ALLOW_THREADS
6806 ok = CreatePipe(&read, &write, NULL, 0);
6807 Py_END_ALLOW_THREADS
6808 if (!ok)
6809 return win32_error("CreatePipe", NULL);
6810 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6811 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6812 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006813#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006814#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006815}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006816#endif /* HAVE_PIPE */
6817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006818
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006819#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006820PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006821"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006822Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006823
Barry Warsaw53699e91996-12-10 23:23:01 +00006824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006825posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006826{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006827 char *filename;
6828 int mode = 0666;
6829 int res;
6830 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6831 return NULL;
6832 Py_BEGIN_ALLOW_THREADS
6833 res = mkfifo(filename, mode);
6834 Py_END_ALLOW_THREADS
6835 if (res < 0)
6836 return posix_error();
6837 Py_INCREF(Py_None);
6838 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006839}
6840#endif
6841
6842
Neal Norwitz11690112002-07-30 01:08:28 +00006843#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006844PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006845"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006846Create a filesystem node (file, device special file or named pipe)\n\
6847named filename. mode specifies both the permissions to use and the\n\
6848type of node to be created, being combined (bitwise OR) with one of\n\
6849S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006850device defines the newly created device special file (probably using\n\
6851os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006852
6853
6854static PyObject *
6855posix_mknod(PyObject *self, PyObject *args)
6856{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006857 char *filename;
6858 int mode = 0600;
6859 int device = 0;
6860 int res;
6861 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6862 return NULL;
6863 Py_BEGIN_ALLOW_THREADS
6864 res = mknod(filename, mode, device);
6865 Py_END_ALLOW_THREADS
6866 if (res < 0)
6867 return posix_error();
6868 Py_INCREF(Py_None);
6869 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006870}
6871#endif
6872
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006873#ifdef HAVE_DEVICE_MACROS
6874PyDoc_STRVAR(posix_major__doc__,
6875"major(device) -> major number\n\
6876Extracts a device major number from a raw device number.");
6877
6878static PyObject *
6879posix_major(PyObject *self, PyObject *args)
6880{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006881 int device;
6882 if (!PyArg_ParseTuple(args, "i:major", &device))
6883 return NULL;
6884 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006885}
6886
6887PyDoc_STRVAR(posix_minor__doc__,
6888"minor(device) -> minor number\n\
6889Extracts a device minor number from a raw device number.");
6890
6891static PyObject *
6892posix_minor(PyObject *self, PyObject *args)
6893{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006894 int device;
6895 if (!PyArg_ParseTuple(args, "i:minor", &device))
6896 return NULL;
6897 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006898}
6899
6900PyDoc_STRVAR(posix_makedev__doc__,
6901"makedev(major, minor) -> device number\n\
6902Composes a raw device number from the major and minor device numbers.");
6903
6904static PyObject *
6905posix_makedev(PyObject *self, PyObject *args)
6906{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006907 int major, minor;
6908 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6909 return NULL;
6910 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006911}
6912#endif /* device macros */
6913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006914
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006915#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006917"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006918Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006919
Barry Warsaw53699e91996-12-10 23:23:01 +00006920static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006921posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006922{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006923 int fd;
6924 off_t length;
6925 int res;
6926 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006927
Victor Stinnerd6f85422010-05-05 23:33:33 +00006928 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6929 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006930
6931#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006932 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006933#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006934 length = PyLong_Check(lenobj) ?
6935 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006936#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006937 if (PyErr_Occurred())
6938 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006939
Victor Stinnerd6f85422010-05-05 23:33:33 +00006940 Py_BEGIN_ALLOW_THREADS
6941 res = ftruncate(fd, length);
6942 Py_END_ALLOW_THREADS
6943 if (res < 0)
6944 return posix_error();
6945 Py_INCREF(Py_None);
6946 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006947}
6948#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006949
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006950#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006951PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006952"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006953Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006954
Fred Drake762e2061999-08-26 17:23:54 +00006955/* Save putenv() parameters as values here, so we can collect them when they
6956 * get re-set with another call for the same key. */
6957static PyObject *posix_putenv_garbage;
6958
Tim Peters5aa91602002-01-30 05:46:57 +00006959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006960posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006961{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006962 char *s1, *s2;
6963 char *newenv;
6964 PyObject *newstr;
6965 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006966
Victor Stinnerd6f85422010-05-05 23:33:33 +00006967 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6968 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006969
6970#if defined(PYOS_OS2)
6971 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6972 APIRET rc;
6973
Guido van Rossumd48f2521997-12-05 22:19:34 +00006974 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6975 if (rc != NO_ERROR)
6976 return os2_error(rc);
6977
6978 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6979 APIRET rc;
6980
Guido van Rossumd48f2521997-12-05 22:19:34 +00006981 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6982 if (rc != NO_ERROR)
6983 return os2_error(rc);
6984 } else {
6985#endif
6986
Victor Stinnerd6f85422010-05-05 23:33:33 +00006987 /* XXX This can leak memory -- not easy to fix :-( */
6988 len = strlen(s1) + strlen(s2) + 2;
6989 /* len includes space for a trailing \0; the size arg to
6990 PyString_FromStringAndSize does not count that */
6991 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6992 if (newstr == NULL)
6993 return PyErr_NoMemory();
6994 newenv = PyString_AS_STRING(newstr);
6995 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6996 if (putenv(newenv)) {
6997 Py_DECREF(newstr);
6998 posix_error();
6999 return NULL;
7000 }
7001 /* Install the first arg and newstr in posix_putenv_garbage;
7002 * this will cause previous value to be collected. This has to
7003 * happen after the real putenv() call because the old value
7004 * was still accessible until then. */
7005 if (PyDict_SetItem(posix_putenv_garbage,
7006 PyTuple_GET_ITEM(args, 0), newstr)) {
7007 /* really not much we can do; just leak */
7008 PyErr_Clear();
7009 }
7010 else {
7011 Py_DECREF(newstr);
7012 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00007013
7014#if defined(PYOS_OS2)
7015 }
7016#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007017 Py_INCREF(Py_None);
7018 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007019}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007020#endif /* putenv */
7021
Guido van Rossumc524d952001-10-19 01:31:59 +00007022#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007023PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007024"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007025Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00007026
7027static PyObject *
7028posix_unsetenv(PyObject *self, PyObject *args)
7029{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007030 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00007031
Victor Stinnerd6f85422010-05-05 23:33:33 +00007032 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
7033 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00007034
Victor Stinnerd6f85422010-05-05 23:33:33 +00007035 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00007036
Victor Stinnerd6f85422010-05-05 23:33:33 +00007037 /* Remove the key from posix_putenv_garbage;
7038 * this will cause it to be collected. This has to
7039 * happen after the real unsetenv() call because the
7040 * old value was still accessible until then.
7041 */
7042 if (PyDict_DelItem(posix_putenv_garbage,
7043 PyTuple_GET_ITEM(args, 0))) {
7044 /* really not much we can do; just leak */
7045 PyErr_Clear();
7046 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007047
Victor Stinnerd6f85422010-05-05 23:33:33 +00007048 Py_INCREF(Py_None);
7049 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007050}
7051#endif /* unsetenv */
7052
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007053PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007054"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007056
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007058posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007059{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007060 int code;
7061 char *message;
7062 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7063 return NULL;
7064 message = strerror(code);
7065 if (message == NULL) {
7066 PyErr_SetString(PyExc_ValueError,
7067 "strerror() argument out of range");
7068 return NULL;
7069 }
7070 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007071}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007072
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007073
Guido van Rossumc9641791998-08-04 15:26:23 +00007074#ifdef HAVE_SYS_WAIT_H
7075
Fred Drake106c1a02002-04-23 15:58:02 +00007076#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007079Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007080
7081static PyObject *
7082posix_WCOREDUMP(PyObject *self, PyObject *args)
7083{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007084 WAIT_TYPE status;
7085 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007086
Victor Stinnerd6f85422010-05-05 23:33:33 +00007087 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7088 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007089
Victor Stinnerd6f85422010-05-05 23:33:33 +00007090 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007091}
7092#endif /* WCOREDUMP */
7093
7094#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007095PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007096"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007097Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007098job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007099
7100static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007101posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007102{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007103 WAIT_TYPE status;
7104 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007105
Victor Stinnerd6f85422010-05-05 23:33:33 +00007106 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7107 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007108
Victor Stinnerd6f85422010-05-05 23:33:33 +00007109 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007110}
7111#endif /* WIFCONTINUED */
7112
Guido van Rossumc9641791998-08-04 15:26:23 +00007113#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007114PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007115"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007116Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007117
7118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007119posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007120{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007121 WAIT_TYPE status;
7122 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007123
Victor Stinnerd6f85422010-05-05 23:33:33 +00007124 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7125 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007126
Victor Stinnerd6f85422010-05-05 23:33:33 +00007127 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007128}
7129#endif /* WIFSTOPPED */
7130
7131#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007132PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007133"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007134Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007135
7136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007137posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007138{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007139 WAIT_TYPE status;
7140 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007141
Victor Stinnerd6f85422010-05-05 23:33:33 +00007142 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007144
Victor Stinnerd6f85422010-05-05 23:33:33 +00007145 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007146}
7147#endif /* WIFSIGNALED */
7148
7149#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007150PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007151"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007152Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007153system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007154
7155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007156posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007157{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007158 WAIT_TYPE status;
7159 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007160
Victor Stinnerd6f85422010-05-05 23:33:33 +00007161 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7162 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007163
Victor Stinnerd6f85422010-05-05 23:33:33 +00007164 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007165}
7166#endif /* WIFEXITED */
7167
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007168#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007170"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007171Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007172
7173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007174posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007175{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007176 WAIT_TYPE status;
7177 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007178
Victor Stinnerd6f85422010-05-05 23:33:33 +00007179 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007181
Victor Stinnerd6f85422010-05-05 23:33:33 +00007182 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007183}
7184#endif /* WEXITSTATUS */
7185
7186#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007187PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007188"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007189Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007190value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007191
7192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007193posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007194{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007195 WAIT_TYPE status;
7196 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007197
Victor Stinnerd6f85422010-05-05 23:33:33 +00007198 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7199 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007200
Victor Stinnerd6f85422010-05-05 23:33:33 +00007201 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007202}
7203#endif /* WTERMSIG */
7204
7205#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007206PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007207"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007208Return the signal that stopped the process that provided\n\
7209the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007210
7211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007212posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007213{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007214 WAIT_TYPE status;
7215 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007216
Victor Stinnerd6f85422010-05-05 23:33:33 +00007217 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7218 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007219
Victor Stinnerd6f85422010-05-05 23:33:33 +00007220 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007221}
7222#endif /* WSTOPSIG */
7223
7224#endif /* HAVE_SYS_WAIT_H */
7225
7226
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007227#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007228#ifdef _SCO_DS
7229/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7230 needed definitions in sys/statvfs.h */
7231#define _SVID3
7232#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007233#include <sys/statvfs.h>
7234
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007235static PyObject*
7236_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007237 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7238 if (v == NULL)
7239 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007240
7241#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007242 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7243 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7244 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7245 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7246 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7247 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7248 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7249 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7250 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7251 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007252#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007253 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7254 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7255 PyStructSequence_SET_ITEM(v, 2,
7256 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7257 PyStructSequence_SET_ITEM(v, 3,
7258 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7259 PyStructSequence_SET_ITEM(v, 4,
7260 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7261 PyStructSequence_SET_ITEM(v, 5,
7262 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7263 PyStructSequence_SET_ITEM(v, 6,
7264 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7265 PyStructSequence_SET_ITEM(v, 7,
7266 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7267 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7268 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007269#endif
7270
Victor Stinnerd6f85422010-05-05 23:33:33 +00007271 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007272}
7273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007274PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007275"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007276Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007277
7278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007279posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007280{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007281 int fd, res;
7282 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007283
Victor Stinnerd6f85422010-05-05 23:33:33 +00007284 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7285 return NULL;
7286 Py_BEGIN_ALLOW_THREADS
7287 res = fstatvfs(fd, &st);
7288 Py_END_ALLOW_THREADS
7289 if (res != 0)
7290 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007291
Victor Stinnerd6f85422010-05-05 23:33:33 +00007292 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007293}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007294#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007295
7296
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007297#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007298#include <sys/statvfs.h>
7299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007300PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007301"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007302Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007303
7304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007305posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007306{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007307 char *path;
7308 int res;
7309 struct statvfs st;
7310 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7311 return NULL;
7312 Py_BEGIN_ALLOW_THREADS
7313 res = statvfs(path, &st);
7314 Py_END_ALLOW_THREADS
7315 if (res != 0)
7316 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007317
Victor Stinnerd6f85422010-05-05 23:33:33 +00007318 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007319}
7320#endif /* HAVE_STATVFS */
7321
7322
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007323#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007324PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007325"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007326Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007327The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007328or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007329
7330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007331posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007332{
7333 PyObject *result = NULL;
7334 char *dir = NULL;
7335 char *pfx = NULL;
7336 char *name;
7337
7338 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007339 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007340
7341 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007342 "tempnam is a potential security risk to your program") < 0)
7343 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007344
Antoine Pitroub0614612011-01-02 20:04:52 +00007345 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7346 "use the tempfile module", 1) < 0)
7347 return NULL;
7348
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007349#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007350 name = _tempnam(dir, pfx);
7351#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007352 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007353#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007354 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007355 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007356 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007357 free(name);
7358 return result;
7359}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007360#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007361
7362
7363#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007364PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007365"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007366Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367
7368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007369posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007370{
7371 FILE *fp;
7372
Antoine Pitroub0614612011-01-02 20:04:52 +00007373 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7374 "use the tempfile module", 1) < 0)
7375 return NULL;
7376
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007377 fp = tmpfile();
7378 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007379 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007380 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007381}
7382#endif
7383
7384
7385#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007386PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007387"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007388Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389
7390static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007391posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392{
7393 char buffer[L_tmpnam];
7394 char *name;
7395
Skip Montanaro95618b52001-08-18 18:52:10 +00007396 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007397 "tmpnam is a potential security risk to your program") < 0)
7398 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007399
Antoine Pitroub0614612011-01-02 20:04:52 +00007400 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7401 "use the tempfile module", 1) < 0)
7402 return NULL;
7403
Greg Wardb48bc172000-03-01 21:51:56 +00007404#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007405 name = tmpnam_r(buffer);
7406#else
7407 name = tmpnam(buffer);
7408#endif
7409 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007410 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007411#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007412 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007413#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007414 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007415#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007416 );
7417 PyErr_SetObject(PyExc_OSError, err);
7418 Py_XDECREF(err);
7419 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007420 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007421 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007422}
7423#endif
7424
7425
Fred Drakec9680921999-12-13 16:37:25 +00007426/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7427 * It maps strings representing configuration variable names to
7428 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007429 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007430 * rarely-used constants. There are three separate tables that use
7431 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007432 *
7433 * This code is always included, even if none of the interfaces that
7434 * need it are included. The #if hackery needed to avoid it would be
7435 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007436 */
7437struct constdef {
7438 char *name;
7439 long value;
7440};
7441
Fred Drake12c6e2d1999-12-14 21:25:03 +00007442static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007443conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007444 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007445{
7446 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007447 *valuep = PyInt_AS_LONG(arg);
7448 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007449 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007450 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007451 /* look up the value in the table using a binary search */
7452 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007453 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007454 size_t hi = tablesize;
7455 int cmp;
7456 char *confname = PyString_AS_STRING(arg);
7457 while (lo < hi) {
7458 mid = (lo + hi) / 2;
7459 cmp = strcmp(confname, table[mid].name);
7460 if (cmp < 0)
7461 hi = mid;
7462 else if (cmp > 0)
7463 lo = mid + 1;
7464 else {
7465 *valuep = table[mid].value;
7466 return 1;
7467 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007468 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007469 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007470 }
7471 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007472 PyErr_SetString(PyExc_TypeError,
7473 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007474 return 0;
7475}
7476
7477
7478#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7479static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007480#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007481 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007482#endif
7483#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007484 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007485#endif
Fred Drakec9680921999-12-13 16:37:25 +00007486#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007487 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007488#endif
7489#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007490 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007491#endif
7492#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007493 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007494#endif
7495#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007496 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007497#endif
7498#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007499 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007500#endif
7501#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007502 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007503#endif
7504#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007505 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007506#endif
7507#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007508 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007509#endif
7510#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007511 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007512#endif
7513#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007514 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007515#endif
7516#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007517 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007518#endif
7519#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007520 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007521#endif
7522#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007523 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007524#endif
7525#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007526 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007527#endif
7528#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007529 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007530#endif
7531};
7532
Fred Drakec9680921999-12-13 16:37:25 +00007533static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007534conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007535{
7536 return conv_confname(arg, valuep, posix_constants_pathconf,
7537 sizeof(posix_constants_pathconf)
7538 / sizeof(struct constdef));
7539}
7540#endif
7541
7542#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007543PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007544"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007545Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007546If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007547
7548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007549posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007550{
7551 PyObject *result = NULL;
7552 int name, fd;
7553
Fred Drake12c6e2d1999-12-14 21:25:03 +00007554 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7555 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007556 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007557
Stefan Krah93f7a322010-11-26 17:35:50 +00007558 errno = 0;
7559 limit = fpathconf(fd, name);
7560 if (limit == -1 && errno != 0)
7561 posix_error();
7562 else
7563 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007564 }
7565 return result;
7566}
7567#endif
7568
7569
7570#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007571PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007572"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007573Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007574If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007575
7576static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007577posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007578{
7579 PyObject *result = NULL;
7580 int name;
7581 char *path;
7582
7583 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7584 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007585 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007586
Victor Stinnerd6f85422010-05-05 23:33:33 +00007587 errno = 0;
7588 limit = pathconf(path, name);
7589 if (limit == -1 && errno != 0) {
7590 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007591 /* could be a path or name problem */
7592 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007593 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007594 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007595 }
7596 else
7597 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007598 }
7599 return result;
7600}
7601#endif
7602
7603#ifdef HAVE_CONFSTR
7604static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007605#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007606 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007607#endif
7608#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007609 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007610#endif
7611#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007612 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007613#endif
7614#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007615 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007616#endif
7617#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007618 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007619#endif
Fred Drakec9680921999-12-13 16:37:25 +00007620#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007621 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007622#endif
7623#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007624 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007625#endif
7626#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007627 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007628#endif
7629#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007630 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007631#endif
7632#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007633 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007634#endif
7635#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007636 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007637#endif
7638#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007639 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007640#endif
7641#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007642 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007643#endif
Fred Draked86ed291999-12-15 15:34:33 +00007644#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007645 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007646#endif
Fred Drakec9680921999-12-13 16:37:25 +00007647#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007648 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007649#endif
Fred Draked86ed291999-12-15 15:34:33 +00007650#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007651 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007652#endif
7653#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007654 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007655#endif
7656#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007657 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007658#endif
7659#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007660 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007661#endif
Fred Drakec9680921999-12-13 16:37:25 +00007662#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007663 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007664#endif
7665#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007666 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007667#endif
7668#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007669 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007670#endif
7671#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007672 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007673#endif
7674#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007675 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007676#endif
7677#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007678 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007679#endif
7680#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007681 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007682#endif
7683#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007684 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007685#endif
7686#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007687 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007688#endif
7689#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007690 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007691#endif
7692#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007693 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007694#endif
7695#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007696 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007697#endif
7698#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007699 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007700#endif
7701#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007702 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007703#endif
7704#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007705 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007706#endif
7707#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007708 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007709#endif
Fred Draked86ed291999-12-15 15:34:33 +00007710#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007711 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007712#endif
7713#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007714 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007715#endif
7716#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007717 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007718#endif
7719#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007720 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007721#endif
7722#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007723 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007724#endif
7725#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007726 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007727#endif
7728#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007729 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007730#endif
7731#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007732 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007733#endif
7734#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007735 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007736#endif
7737#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007738 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007739#endif
7740#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007741 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007742#endif
7743#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007744 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007745#endif
7746#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007747 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007748#endif
Fred Drakec9680921999-12-13 16:37:25 +00007749};
7750
7751static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007752conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007753{
7754 return conv_confname(arg, valuep, posix_constants_confstr,
7755 sizeof(posix_constants_confstr)
7756 / sizeof(struct constdef));
7757}
7758
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007759PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007760"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007761Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007762
7763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007764posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007765{
7766 PyObject *result = NULL;
7767 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007768 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007769
7770 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007771 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007772
Victor Stinnerd6f85422010-05-05 23:33:33 +00007773 errno = 0;
7774 len = confstr(name, buffer, sizeof(buffer));
7775 if (len == 0) {
7776 if (errno) {
7777 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007778 }
7779 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007780 result = Py_None;
7781 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007782 }
7783 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007784 else {
7785 if ((unsigned int)len >= sizeof(buffer)) {
7786 result = PyString_FromStringAndSize(NULL, len-1);
7787 if (result != NULL)
7788 confstr(name, PyString_AS_STRING(result), len);
7789 }
7790 else
7791 result = PyString_FromStringAndSize(buffer, len-1);
7792 }
7793 }
Fred Drakec9680921999-12-13 16:37:25 +00007794 return result;
7795}
7796#endif
7797
7798
7799#ifdef HAVE_SYSCONF
7800static struct constdef posix_constants_sysconf[] = {
7801#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007802 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007803#endif
7804#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007805 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007806#endif
7807#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007808 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007809#endif
7810#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007811 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007812#endif
7813#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007814 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007815#endif
7816#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007817 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007818#endif
7819#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007820 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007821#endif
7822#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007823 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007824#endif
7825#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007826 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007827#endif
7828#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007829 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007830#endif
Fred Draked86ed291999-12-15 15:34:33 +00007831#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007832 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007833#endif
7834#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007835 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007836#endif
Fred Drakec9680921999-12-13 16:37:25 +00007837#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007838 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007839#endif
Fred Drakec9680921999-12-13 16:37:25 +00007840#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007841 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007842#endif
7843#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007844 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007845#endif
7846#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007847 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007848#endif
7849#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007850 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007851#endif
7852#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007853 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007854#endif
Fred Draked86ed291999-12-15 15:34:33 +00007855#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007856 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007857#endif
Fred Drakec9680921999-12-13 16:37:25 +00007858#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007859 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007860#endif
7861#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007862 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007863#endif
7864#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007865 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007866#endif
7867#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007868 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007869#endif
7870#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007871 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007872#endif
Fred Draked86ed291999-12-15 15:34:33 +00007873#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007874 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007875#endif
Fred Drakec9680921999-12-13 16:37:25 +00007876#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007877 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007878#endif
7879#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007880 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007881#endif
7882#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007883 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007884#endif
7885#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007886 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007887#endif
7888#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007889 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007890#endif
7891#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007892 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007893#endif
7894#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007895 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007896#endif
7897#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007898 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007899#endif
7900#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007901 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007902#endif
7903#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007904 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007905#endif
7906#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007907 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007908#endif
7909#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007910 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007911#endif
7912#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007913 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007914#endif
7915#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007916 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007917#endif
7918#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007919 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007920#endif
7921#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007922 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007923#endif
7924#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007925 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007926#endif
7927#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007928 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007929#endif
7930#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007931 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007932#endif
7933#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007934 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007935#endif
7936#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007937 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007938#endif
7939#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007940 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007941#endif
7942#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007943 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007944#endif
Fred Draked86ed291999-12-15 15:34:33 +00007945#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007946 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007947#endif
Fred Drakec9680921999-12-13 16:37:25 +00007948#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007949 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007950#endif
7951#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007952 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007953#endif
7954#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007955 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007956#endif
Fred Draked86ed291999-12-15 15:34:33 +00007957#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007958 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007959#endif
Fred Drakec9680921999-12-13 16:37:25 +00007960#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007961 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007962#endif
Fred Draked86ed291999-12-15 15:34:33 +00007963#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007964 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007965#endif
7966#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007967 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007968#endif
Fred Drakec9680921999-12-13 16:37:25 +00007969#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007970 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007971#endif
7972#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007973 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007974#endif
7975#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007976 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007977#endif
7978#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007979 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007980#endif
Fred Draked86ed291999-12-15 15:34:33 +00007981#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007982 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007983#endif
Fred Drakec9680921999-12-13 16:37:25 +00007984#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007985 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007986#endif
7987#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007988 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007989#endif
7990#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007991 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007992#endif
7993#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007994 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007995#endif
7996#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007997 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007998#endif
7999#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008000 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00008001#endif
8002#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008003 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00008004#endif
Fred Draked86ed291999-12-15 15:34:33 +00008005#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008006 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00008007#endif
Fred Drakec9680921999-12-13 16:37:25 +00008008#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008009 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008010#endif
8011#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008012 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008013#endif
Fred Draked86ed291999-12-15 15:34:33 +00008014#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008015 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00008016#endif
Fred Drakec9680921999-12-13 16:37:25 +00008017#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008018 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008019#endif
8020#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008021 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008022#endif
8023#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008024 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008025#endif
8026#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008027 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008028#endif
8029#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008030 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008031#endif
8032#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008033 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008034#endif
8035#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008036 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008037#endif
8038#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008039 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008040#endif
8041#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008042 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008043#endif
Fred Draked86ed291999-12-15 15:34:33 +00008044#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008045 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008046#endif
8047#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008048 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008049#endif
Fred Drakec9680921999-12-13 16:37:25 +00008050#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008051 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008052#endif
8053#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008054 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008055#endif
8056#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008057 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008058#endif
8059#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008060 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008061#endif
8062#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008063 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008064#endif
8065#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008066 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008067#endif
8068#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008069 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008070#endif
8071#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008072 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008073#endif
8074#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008075 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008076#endif
8077#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008078 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008079#endif
8080#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008081 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008082#endif
8083#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008084 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008085#endif
8086#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008087 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008088#endif
8089#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008090 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008091#endif
8092#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008093 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008094#endif
8095#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008096 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008097#endif
8098#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008099 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008100#endif
8101#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008102 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008103#endif
8104#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008105 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008106#endif
8107#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008108 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008109#endif
8110#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008111 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008112#endif
8113#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008114 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008115#endif
8116#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008117 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008118#endif
8119#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008120 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008121#endif
8122#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008123 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008124#endif
8125#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008126 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008127#endif
8128#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008129 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008130#endif
8131#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008132 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008133#endif
8134#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008135 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008136#endif
8137#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008138 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008139#endif
8140#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008141 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008142#endif
8143#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008144 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008145#endif
8146#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008147 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008148#endif
8149#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008150 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008151#endif
8152#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008153 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008154#endif
Fred Draked86ed291999-12-15 15:34:33 +00008155#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008156 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008157#endif
Fred Drakec9680921999-12-13 16:37:25 +00008158#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008159 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008160#endif
8161#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008162 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008163#endif
8164#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008165 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008166#endif
8167#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008168 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008169#endif
8170#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008171 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008172#endif
8173#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008174 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008175#endif
8176#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008177 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008178#endif
8179#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008180 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008181#endif
8182#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008183 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008184#endif
8185#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008186 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008187#endif
8188#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008189 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008190#endif
8191#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008192 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008193#endif
8194#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008195 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008196#endif
8197#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008198 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008199#endif
8200#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008201 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008202#endif
8203#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008204 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008205#endif
8206#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008207 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008208#endif
8209#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008210 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008211#endif
8212#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008213 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008214#endif
8215#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008216 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008217#endif
8218#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008219 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008220#endif
8221#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008222 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008223#endif
8224#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008225 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008226#endif
8227#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008228 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008229#endif
8230#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008231 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008232#endif
8233#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008234 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008235#endif
8236#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008237 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008238#endif
8239#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008240 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008241#endif
8242#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008243 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008244#endif
8245#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008246 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008247#endif
8248#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008249 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008250#endif
8251#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008252 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008253#endif
8254#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008255 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008256#endif
8257#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008258 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008259#endif
8260#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008261 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008262#endif
8263#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008264 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008265#endif
8266#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008267 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008268#endif
8269#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008270 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008271#endif
8272#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008273 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008274#endif
8275#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008276 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008277#endif
8278#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008279 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008280#endif
8281#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008282 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008283#endif
8284#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008285 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008286#endif
8287#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008288 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008289#endif
8290#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008291 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008292#endif
8293};
8294
8295static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008296conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008297{
8298 return conv_confname(arg, valuep, posix_constants_sysconf,
8299 sizeof(posix_constants_sysconf)
8300 / sizeof(struct constdef));
8301}
8302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008303PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008304"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008305Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008306
8307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008308posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008309{
8310 PyObject *result = NULL;
8311 int name;
8312
8313 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008314 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008315
Victor Stinner862490a2010-05-06 00:03:44 +00008316 errno = 0;
8317 value = sysconf(name);
8318 if (value == -1 && errno != 0)
8319 posix_error();
8320 else
8321 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008322 }
8323 return result;
8324}
8325#endif
8326
8327
Fred Drakebec628d1999-12-15 18:31:10 +00008328/* This code is used to ensure that the tables of configuration value names
8329 * are in sorted order as required by conv_confname(), and also to build the
8330 * the exported dictionaries that are used to publish information about the
8331 * names available on the host platform.
8332 *
8333 * Sorting the table at runtime ensures that the table is properly ordered
8334 * when used, even for platforms we're not able to test on. It also makes
8335 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008336 */
Fred Drakebec628d1999-12-15 18:31:10 +00008337
8338static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008339cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008340{
8341 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008342 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008343 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008344 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008345
8346 return strcmp(c1->name, c2->name);
8347}
8348
8349static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008350setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008351 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008352{
Fred Drakebec628d1999-12-15 18:31:10 +00008353 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008354 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008355
8356 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8357 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008358 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008359 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008360
Barry Warsaw3155db32000-04-13 15:20:40 +00008361 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008362 PyObject *o = PyInt_FromLong(table[i].value);
8363 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8364 Py_XDECREF(o);
8365 Py_DECREF(d);
8366 return -1;
8367 }
8368 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008369 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008370 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008371}
8372
Fred Drakebec628d1999-12-15 18:31:10 +00008373/* Return -1 on failure, 0 on success. */
8374static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008375setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008376{
8377#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008378 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008379 sizeof(posix_constants_pathconf)
8380 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008381 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008382 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008383#endif
8384#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008385 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008386 sizeof(posix_constants_confstr)
8387 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008388 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008389 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008390#endif
8391#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008392 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008393 sizeof(posix_constants_sysconf)
8394 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008395 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008396 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008397#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008398 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008399}
Fred Draked86ed291999-12-15 15:34:33 +00008400
8401
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008402PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008403"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008404Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008405in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008406
8407static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008408posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008409{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008410 abort();
8411 /*NOTREACHED*/
8412 Py_FatalError("abort() called from Python code didn't abort!");
8413 return NULL;
8414}
Fred Drakebec628d1999-12-15 18:31:10 +00008415
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008416#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008417PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008418"startfile(filepath [, operation]) - Start a file with its associated\n\
8419application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008420\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008421When \"operation\" is not specified or \"open\", this acts like\n\
8422double-clicking the file in Explorer, or giving the file name as an\n\
8423argument to the DOS \"start\" command: the file is opened with whatever\n\
8424application (if any) its extension is associated.\n\
8425When another \"operation\" is given, it specifies what should be done with\n\
8426the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008427\n\
8428startfile returns as soon as the associated application is launched.\n\
8429There is no option to wait for the application to close, and no way\n\
8430to retrieve the application's exit status.\n\
8431\n\
8432The filepath is relative to the current directory. If you want to use\n\
8433an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008434the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008435
8436static PyObject *
8437win32_startfile(PyObject *self, PyObject *args)
8438{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008439 char *filepath;
8440 char *operation = NULL;
8441 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008442
Victor Stinnerd6f85422010-05-05 23:33:33 +00008443 PyObject *unipath, *woperation = NULL;
8444 if (!PyArg_ParseTuple(args, "U|s:startfile",
8445 &unipath, &operation)) {
8446 PyErr_Clear();
8447 goto normal;
8448 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008449
Victor Stinnerd6f85422010-05-05 23:33:33 +00008450 if (operation) {
8451 woperation = PyUnicode_DecodeASCII(operation,
8452 strlen(operation), NULL);
8453 if (!woperation) {
8454 PyErr_Clear();
8455 operation = NULL;
8456 goto normal;
8457 }
8458 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008459
Victor Stinnerd6f85422010-05-05 23:33:33 +00008460 Py_BEGIN_ALLOW_THREADS
8461 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8462 PyUnicode_AS_UNICODE(unipath),
8463 NULL, NULL, SW_SHOWNORMAL);
8464 Py_END_ALLOW_THREADS
8465
8466 Py_XDECREF(woperation);
8467 if (rc <= (HINSTANCE)32) {
8468 PyObject *errval = win32_error_unicode("startfile",
8469 PyUnicode_AS_UNICODE(unipath));
8470 return errval;
8471 }
8472 Py_INCREF(Py_None);
8473 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008474
8475normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008476 if (!PyArg_ParseTuple(args, "et|s:startfile",
8477 Py_FileSystemDefaultEncoding, &filepath,
8478 &operation))
8479 return NULL;
8480 Py_BEGIN_ALLOW_THREADS
8481 rc = ShellExecute((HWND)0, operation, filepath,
8482 NULL, NULL, SW_SHOWNORMAL);
8483 Py_END_ALLOW_THREADS
8484 if (rc <= (HINSTANCE)32) {
8485 PyObject *errval = win32_error("startfile", filepath);
8486 PyMem_Free(filepath);
8487 return errval;
8488 }
8489 PyMem_Free(filepath);
8490 Py_INCREF(Py_None);
8491 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008492}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008493#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008494
Martin v. Löwis438b5342002-12-27 10:16:42 +00008495#ifdef HAVE_GETLOADAVG
8496PyDoc_STRVAR(posix_getloadavg__doc__,
8497"getloadavg() -> (float, float, float)\n\n\
8498Return the number of processes in the system run queue averaged over\n\
8499the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8500was unobtainable");
8501
8502static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008503posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008504{
8505 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008506 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008507 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8508 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008509 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008510 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008511}
8512#endif
8513
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008514#ifdef MS_WINDOWS
8515
8516PyDoc_STRVAR(win32_urandom__doc__,
8517"urandom(n) -> str\n\n\
8518Return a string of n random bytes suitable for cryptographic use.");
8519
8520typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8521 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8522 DWORD dwFlags );
8523typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8524 BYTE *pbBuffer );
8525
8526static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008527/* This handle is never explicitly released. Instead, the operating
8528 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008529static HCRYPTPROV hCryptProv = 0;
8530
Tim Peters4ad82172004-08-30 17:02:04 +00008531static PyObject*
8532win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008533{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008534 int howMany;
8535 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008536
Victor Stinnerd6f85422010-05-05 23:33:33 +00008537 /* Read arguments */
8538 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8539 return NULL;
8540 if (howMany < 0)
8541 return PyErr_Format(PyExc_ValueError,
8542 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008543
Victor Stinnerd6f85422010-05-05 23:33:33 +00008544 if (hCryptProv == 0) {
8545 HINSTANCE hAdvAPI32 = NULL;
8546 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008547
Victor Stinnerd6f85422010-05-05 23:33:33 +00008548 /* Obtain handle to the DLL containing CryptoAPI
8549 This should not fail */
8550 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8551 if(hAdvAPI32 == NULL)
8552 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008553
Victor Stinnerd6f85422010-05-05 23:33:33 +00008554 /* Obtain pointers to the CryptoAPI functions
8555 This will fail on some early versions of Win95 */
8556 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8557 hAdvAPI32,
8558 "CryptAcquireContextA");
8559 if (pCryptAcquireContext == NULL)
8560 return PyErr_Format(PyExc_NotImplementedError,
8561 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008562
Victor Stinnerd6f85422010-05-05 23:33:33 +00008563 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8564 hAdvAPI32, "CryptGenRandom");
8565 if (pCryptGenRandom == NULL)
8566 return PyErr_Format(PyExc_NotImplementedError,
8567 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008568
Victor Stinnerd6f85422010-05-05 23:33:33 +00008569 /* Acquire context */
8570 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8571 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8572 return win32_error("CryptAcquireContext", NULL);
8573 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008574
Victor Stinnerd6f85422010-05-05 23:33:33 +00008575 /* Allocate bytes */
8576 result = PyString_FromStringAndSize(NULL, howMany);
8577 if (result != NULL) {
8578 /* Get random data */
8579 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8580 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8581 PyString_AS_STRING(result))) {
8582 Py_DECREF(result);
8583 return win32_error("CryptGenRandom", NULL);
8584 }
8585 }
8586 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008587}
8588#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008589
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008590#ifdef __VMS
8591/* Use openssl random routine */
8592#include <openssl/rand.h>
8593PyDoc_STRVAR(vms_urandom__doc__,
8594"urandom(n) -> str\n\n\
8595Return a string of n random bytes suitable for cryptographic use.");
8596
8597static PyObject*
8598vms_urandom(PyObject *self, PyObject *args)
8599{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008600 int howMany;
8601 PyObject* result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008602
Victor Stinnerd6f85422010-05-05 23:33:33 +00008603 /* Read arguments */
8604 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8605 return NULL;
8606 if (howMany < 0)
8607 return PyErr_Format(PyExc_ValueError,
8608 "negative argument not allowed");
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008609
Victor Stinnerd6f85422010-05-05 23:33:33 +00008610 /* Allocate bytes */
8611 result = PyString_FromStringAndSize(NULL, howMany);
8612 if (result != NULL) {
8613 /* Get random data */
8614 if (RAND_pseudo_bytes((unsigned char*)
8615 PyString_AS_STRING(result),
8616 howMany) < 0) {
8617 Py_DECREF(result);
8618 return PyErr_Format(PyExc_ValueError,
8619 "RAND_pseudo_bytes");
8620 }
8621 }
8622 return result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008623}
8624#endif
8625
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008626#ifdef HAVE_SETRESUID
8627PyDoc_STRVAR(posix_setresuid__doc__,
8628"setresuid(ruid, euid, suid)\n\n\
8629Set the current process's real, effective, and saved user ids.");
8630
8631static PyObject*
8632posix_setresuid (PyObject *self, PyObject *args)
8633{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008634 /* We assume uid_t is no larger than a long. */
8635 long ruid, euid, suid;
8636 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8637 return NULL;
8638 if (setresuid(ruid, euid, suid) < 0)
8639 return posix_error();
8640 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008641}
8642#endif
8643
8644#ifdef HAVE_SETRESGID
8645PyDoc_STRVAR(posix_setresgid__doc__,
8646"setresgid(rgid, egid, sgid)\n\n\
8647Set the current process's real, effective, and saved group ids.");
8648
8649static PyObject*
8650posix_setresgid (PyObject *self, PyObject *args)
8651{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008652 /* We assume uid_t is no larger than a long. */
8653 long rgid, egid, sgid;
8654 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8655 return NULL;
8656 if (setresgid(rgid, egid, sgid) < 0)
8657 return posix_error();
8658 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008659}
8660#endif
8661
8662#ifdef HAVE_GETRESUID
8663PyDoc_STRVAR(posix_getresuid__doc__,
8664"getresuid() -> (ruid, euid, suid)\n\n\
8665Get tuple of the current process's real, effective, and saved user ids.");
8666
8667static PyObject*
8668posix_getresuid (PyObject *self, PyObject *noargs)
8669{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008670 uid_t ruid, euid, suid;
8671 long l_ruid, l_euid, l_suid;
8672 if (getresuid(&ruid, &euid, &suid) < 0)
8673 return posix_error();
8674 /* Force the values into long's as we don't know the size of uid_t. */
8675 l_ruid = ruid;
8676 l_euid = euid;
8677 l_suid = suid;
8678 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008679}
8680#endif
8681
8682#ifdef HAVE_GETRESGID
8683PyDoc_STRVAR(posix_getresgid__doc__,
8684"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008685Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008686
8687static PyObject*
8688posix_getresgid (PyObject *self, PyObject *noargs)
8689{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008690 uid_t rgid, egid, sgid;
8691 long l_rgid, l_egid, l_sgid;
8692 if (getresgid(&rgid, &egid, &sgid) < 0)
8693 return posix_error();
8694 /* Force the values into long's as we don't know the size of uid_t. */
8695 l_rgid = rgid;
8696 l_egid = egid;
8697 l_sgid = sgid;
8698 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008699}
8700#endif
8701
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008702static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008703 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008704#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008705 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008706#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008707 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008708#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008709 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008710#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008711 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008712#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008713 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008714#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008715#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008716 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008717#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008718#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008719 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008720#endif /* HAVE_LCHMOD */
8721#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008722 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008723#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008724#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008725 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008726#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008727#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008728 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008729#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008730#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008731 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008732#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008733#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008734 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008735#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008736#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008737 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008738#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008739 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008740#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008741#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008742#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008743 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008744#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008745 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8746 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8747 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008748#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008749 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008750#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008751#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008752 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008753#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008754 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8755 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8756 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8757 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008758#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008759 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008760#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008761#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008762 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008763#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008764 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008765#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008766 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008767#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008768 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8769 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8770 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008771#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008772 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008773#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008774 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008775#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008776 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8777 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008778#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008779#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008780 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8781 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008782#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008783 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8784 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008785#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008786#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008787#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008788 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008789#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008790#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008791 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008792#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008793#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008794 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008795#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008796#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008797 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008798#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008799#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008800 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008801#endif /* HAVE_GETEGID */
8802#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008803 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008804#endif /* HAVE_GETEUID */
8805#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008806 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008807#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008808#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008809 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008810#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008811 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008812#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008813 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008814#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008815#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008816 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008817#endif /* HAVE_GETPPID */
8818#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008819 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008820#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008821#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008822 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008823#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008824#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008825 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008826#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008827#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008828 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008829#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008830#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008831 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008832#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008833#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008834 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008835#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"popen2", win32_popen2, METH_VARARGS},
8837 {"popen3", win32_popen3, METH_VARARGS},
8838 {"popen4", win32_popen4, METH_VARARGS},
8839 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8840 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008841#else
8842#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008843 {"popen2", os2emx_popen2, METH_VARARGS},
8844 {"popen3", os2emx_popen3, METH_VARARGS},
8845 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008846#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008847#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008848#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008849#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008850 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008851#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008852#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008853 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008854#endif /* HAVE_SETEUID */
8855#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008856 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008857#endif /* HAVE_SETEGID */
8858#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008859 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008860#endif /* HAVE_SETREUID */
8861#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008862 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008863#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008864#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008865 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008866#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008867#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008869#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008870#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008871 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008872#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008873#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008874 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008875#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008876#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008877 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008878#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008879#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008881#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008882#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008883 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008884#endif /* HAVE_WAIT3 */
8885#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008887#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008888#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008889 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008890#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008891#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008892 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008893#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008894#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008896#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008897#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008898 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008899#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008900#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008902#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008903#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008904 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008905#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008906 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8907 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8908 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8909 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8910 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8911 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8912 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8913 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8914 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8915 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8916 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008917#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008918 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008919#endif
8920#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008921 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008922#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008923#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008925#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008926#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008927 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8928 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8929 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008930#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008931#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008933#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008934#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008936#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008937#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008938 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008939#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008940 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008941#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008942 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008943#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008944#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008945 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008946#endif
8947#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008949#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008950#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008951#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008953#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008954#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008955 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008956#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008957#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008958 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008959#endif /* WIFSTOPPED */
8960#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008961 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008962#endif /* WIFSIGNALED */
8963#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008964 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008965#endif /* WIFEXITED */
8966#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008967 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008968#endif /* WEXITSTATUS */
8969#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008970 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008971#endif /* WTERMSIG */
8972#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008973 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008974#endif /* WSTOPSIG */
8975#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008976#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008977 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008978#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008979#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008980 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008981#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008982#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008983 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008984#endif
8985#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008986 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008987#endif
8988#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008989 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008990#endif
Fred Drakec9680921999-12-13 16:37:25 +00008991#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008992 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008993#endif
8994#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008995 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008996#endif
8997#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008998 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008999#endif
9000#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00009001 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009003 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00009004#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009005 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtincaea7e82011-06-08 19:29:53 -05009006 {"_isdir", posix__isdir, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00009007#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00009008#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009009 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00009010#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009011 #ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009012 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00009013 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00009014 #ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009015 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Neal Norwitz2a30cd02006-07-10 01:18:57 +00009016 #endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009017#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009018 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009019#endif
9020#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009021 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009022#endif
9023#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009024 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009025#endif
9026#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00009027 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00009028#endif
9029
Victor Stinnerd6f85422010-05-05 23:33:33 +00009030 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009031};
9032
9033
Barry Warsaw4a342091996-12-19 23:50:02 +00009034static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00009035ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00009036{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009038}
9039
Guido van Rossumd48f2521997-12-05 22:19:34 +00009040#if defined(PYOS_OS2)
9041/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009042static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009043{
9044 APIRET rc;
9045 ULONG values[QSV_MAX+1];
9046 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009047 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009048
9049 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009050 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009051 Py_END_ALLOW_THREADS
9052
9053 if (rc != NO_ERROR) {
9054 os2_error(rc);
9055 return -1;
9056 }
9057
Fred Drake4d1e64b2002-04-15 19:40:07 +00009058 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9059 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9060 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9061 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9062 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9063 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9064 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009065
9066 switch (values[QSV_VERSION_MINOR]) {
9067 case 0: ver = "2.00"; break;
9068 case 10: ver = "2.10"; break;
9069 case 11: ver = "2.11"; break;
9070 case 30: ver = "3.00"; break;
9071 case 40: ver = "4.00"; break;
9072 case 50: ver = "5.00"; break;
9073 default:
Tim Peters885d4572001-11-28 20:27:42 +00009074 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009075 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009076 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009077 ver = &tmp[0];
9078 }
9079
9080 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009081 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009082 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009083
9084 /* Add Indicator of Which Drive was Used to Boot the System */
9085 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9086 tmp[1] = ':';
9087 tmp[2] = '\0';
9088
Fred Drake4d1e64b2002-04-15 19:40:07 +00009089 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009090}
9091#endif
9092
Barry Warsaw4a342091996-12-19 23:50:02 +00009093static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009094all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009095{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009096#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009098#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009099#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009101#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009102#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009103 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009104#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009105#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009106 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009107#endif
Fred Drakec9680921999-12-13 16:37:25 +00009108#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009109 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009110#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009111#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009112 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009113#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009114#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009115 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009116#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009117#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009119#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009120#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009122#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009123#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009124 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009125#endif
9126#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009127 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009128#endif
9129#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009131#endif
9132#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009133 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009134#endif
9135#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009136 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009137#endif
9138#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009139 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009140#endif
9141#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009142 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009143#endif
9144#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009145 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009146#endif
9147#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009148 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009149#endif
9150#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009151 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009152#endif
9153#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009154 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009155#endif
9156#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009157 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009158#endif
9159#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009160 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009161#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009162#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009163 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009164#endif
9165#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009166 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009167#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009168#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009169 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009170#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009171#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009172 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009173#endif
9174#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009175 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009176#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009177
Tim Peters5aa91602002-01-30 05:46:57 +00009178/* MS Windows */
9179#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009180 /* Don't inherit in child processes. */
9181 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009182#endif
9183#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009184 /* Optimize for short life (keep in memory). */
9185 /* MS forgot to define this one with a non-underscore form too. */
9186 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009187#endif
9188#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009189 /* Automatically delete when last handle is closed. */
9190 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009191#endif
9192#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009193 /* Optimize for random access. */
9194 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009195#endif
9196#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009197 /* Optimize for sequential access. */
9198 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009199#endif
9200
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009201/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009202#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009203 /* Send a SIGIO signal whenever input or output
9204 becomes available on file descriptor */
9205 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009206#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009207#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009208 /* Direct disk access. */
9209 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009210#endif
9211#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009212 /* Must be a directory. */
9213 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009214#endif
9215#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009216 /* Do not follow links. */
9217 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009218#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009219#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009220 /* Do not update the access time. */
9221 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009222#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009223
Victor Stinnerd6f85422010-05-05 23:33:33 +00009224 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009225#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009226 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009227#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009228#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009229 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009230#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009231#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009232 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009233#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009234#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009235 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009236#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009237#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009238 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009239#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009240#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009242#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009243#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009244 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009245#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009246#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009247 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009248#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009249#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009250 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009251#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009252#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009253 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009254#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009255#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009256 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009257#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009258#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009259 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009260#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009261#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009262 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009263#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009264#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009265 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009266#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009267#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009268 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009269#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009270#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009271 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009272#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009273#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009274 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009275#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009276
Guido van Rossum246bc171999-02-01 23:54:31 +00009277#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009278#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009279 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9280 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9281 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9282 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9283 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9284 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9285 if (ins(d, "P_PM", (long)P_PM)) return -1;
9286 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9287 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9288 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9289 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9290 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9291 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9292 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9293 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9294 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9295 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9296 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9297 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9298 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009299#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009300 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9301 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9302 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9303 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9304 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009305#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009306#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009307
Guido van Rossumd48f2521997-12-05 22:19:34 +00009308#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009309 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009310#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009311 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009312}
9313
9314
Tim Peters5aa91602002-01-30 05:46:57 +00009315#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009316#define INITFUNC initnt
9317#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009318
9319#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009320#define INITFUNC initos2
9321#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009322
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009323#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009324#define INITFUNC initposix
9325#define MODNAME "posix"
9326#endif
9327
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009328PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009329INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009330{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009331 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009332
Victor Stinnerd6f85422010-05-05 23:33:33 +00009333 m = Py_InitModule3(MODNAME,
9334 posix_methods,
9335 posix__doc__);
9336 if (m == NULL)
9337 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009338
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 /* Initialize environ dictionary */
9340 v = convertenviron();
9341 Py_XINCREF(v);
9342 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9343 return;
9344 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009345
Victor Stinnerd6f85422010-05-05 23:33:33 +00009346 if (all_ins(m))
9347 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009348
Victor Stinnerd6f85422010-05-05 23:33:33 +00009349 if (setup_confname_tables(m))
9350 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009351
Victor Stinnerd6f85422010-05-05 23:33:33 +00009352 Py_INCREF(PyExc_OSError);
9353 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009354
Guido van Rossumb3d39562000-01-31 18:41:26 +00009355#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009356 if (posix_putenv_garbage == NULL)
9357 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009358#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009359
Victor Stinnerd6f85422010-05-05 23:33:33 +00009360 if (!initialized) {
9361 stat_result_desc.name = MODNAME ".stat_result";
9362 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9363 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9364 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9365 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9366 structseq_new = StatResultType.tp_new;
9367 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009368
Victor Stinnerd6f85422010-05-05 23:33:33 +00009369 statvfs_result_desc.name = MODNAME ".statvfs_result";
9370 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009371#ifdef NEED_TICKS_PER_SECOND
9372# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009373 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009374# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009375 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009376# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009377 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009378# endif
9379#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009380 }
9381 Py_INCREF((PyObject*) &StatResultType);
9382 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9383 Py_INCREF((PyObject*) &StatVFSResultType);
9384 PyModule_AddObject(m, "statvfs_result",
9385 (PyObject*) &StatVFSResultType);
9386 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009387
9388#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009389 /*
9390 * Step 2 of weak-linking support on Mac OS X.
9391 *
9392 * The code below removes functions that are not available on the
9393 * currently active platform.
9394 *
9395 * This block allow one to use a python binary that was build on
9396 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9397 * OSX 10.4.
9398 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009399#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009400 if (fstatvfs == NULL) {
9401 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9402 return;
9403 }
9404 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009405#endif /* HAVE_FSTATVFS */
9406
9407#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009408 if (statvfs == NULL) {
9409 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9410 return;
9411 }
9412 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009413#endif /* HAVE_STATVFS */
9414
9415# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009416 if (lchown == NULL) {
9417 if (PyObject_DelAttrString(m, "lchown") == -1) {
9418 return;
9419 }
9420 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009421#endif /* HAVE_LCHOWN */
9422
9423
9424#endif /* __APPLE__ */
9425
Guido van Rossumb6775db1994-08-01 11:34:53 +00009426}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009427
9428#ifdef __cplusplus
9429}
9430#endif
9431
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009432