blob: 8066d457d115fd4d960e406153865d9cf61d2ff1 [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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000343#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000344# define STAT win32_stat
345# define FSTAT win32_fstat
346# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000347#else
Victor Stinnerd6f85422010-05-05 23:33:33 +0000348# define STAT stat
349# define FSTAT fstat
350# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000351#endif
352
Tim Peters11b23062003-04-23 02:39:17 +0000353#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000354#include <sys/mkdev.h>
355#else
356#if defined(MAJOR_IN_SYSMACROS)
357#include <sys/sysmacros.h>
358#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000359#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
360#include <sys/mkdev.h>
361#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000362#endif
Fred Drake699f3522000-06-29 21:12:41 +0000363
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000364#if defined _MSC_VER && _MSC_VER >= 1400
365/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
366 * valid and throw an assertion if it isn't.
367 * Normally, an invalid fd is likely to be a C program error and therefore
368 * an assertion can be useful, but it does contradict the POSIX standard
369 * which for write(2) states:
370 * "Otherwise, -1 shall be returned and errno set to indicate the error."
371 * "[EBADF] The fildes argument is not a valid file descriptor open for
372 * writing."
373 * Furthermore, python allows the user to enter any old integer
374 * as a fd and should merely raise a python exception on error.
375 * The Microsoft CRT doesn't provide an official way to check for the
376 * validity of a file descriptor, but we can emulate its internal behaviour
Victor Stinnerd6f85422010-05-05 23:33:33 +0000377 * by using the exported __pinfo data member and knowledge of the
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000378 * internal structures involved.
379 * The structures below must be updated for each version of visual studio
380 * according to the file internal.h in the CRT source, until MS comes
381 * up with a less hacky way to do this.
382 * (all of this is to avoid globally modifying the CRT behaviour using
383 * _set_invalid_parameter_handler() and _CrtSetReportMode())
384 */
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000385/* The actual size of the structure is determined at runtime.
386 * Only the first items must be present.
387 */
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000388typedef struct {
Victor Stinnerd6f85422010-05-05 23:33:33 +0000389 intptr_t osfhnd;
390 char osfile;
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000391} my_ioinfo;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000392
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000393extern __declspec(dllimport) char * __pioinfo[];
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000394#define IOINFO_L2E 5
395#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
396#define IOINFO_ARRAYS 64
397#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
398#define FOPEN 0x01
399#define _NO_CONSOLE_FILENO (intptr_t)-2
400
401/* This function emulates what the windows CRT does to validate file handles */
402int
403_PyVerify_fd(int fd)
404{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000405 const int i1 = fd >> IOINFO_L2E;
406 const int i2 = fd & ((1 << IOINFO_L2E) - 1);
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000407
Victor Stinnerd6f85422010-05-05 23:33:33 +0000408 static int sizeof_ioinfo = 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000409
Victor Stinnerd6f85422010-05-05 23:33:33 +0000410 /* Determine the actual size of the ioinfo structure,
411 * as used by the CRT loaded in memory
412 */
413 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) {
414 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS;
415 }
416 if (sizeof_ioinfo == 0) {
417 /* This should not happen... */
418 goto fail;
419 }
420
421 /* See that it isn't a special CLEAR fileno */
422 if (fd != _NO_CONSOLE_FILENO) {
423 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead
424 * we check pointer validity and other info
425 */
426 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
427 /* finally, check that the file is open */
428 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo);
429 if (info->osfile & FOPEN) {
430 return 1;
431 }
432 }
433 }
Kristján Valur Jónssonfeab3342009-04-01 16:08:34 +0000434 fail:
Victor Stinnerd6f85422010-05-05 23:33:33 +0000435 errno = EBADF;
436 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000437}
438
439/* the special case of checking dup2. The target fd must be in a sensible range */
440static int
441_PyVerify_fd_dup2(int fd1, int fd2)
442{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000443 if (!_PyVerify_fd(fd1))
444 return 0;
445 if (fd2 == _NO_CONSOLE_FILENO)
446 return 0;
447 if ((unsigned)fd2 < _NHANDLE_)
448 return 1;
449 else
450 return 0;
Kristján Valur Jónsson6a743d32009-02-10 13:32:24 +0000451}
452#else
453/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
454#define _PyVerify_fd_dup2(A, B) (1)
455#endif
456
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000457/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000458#ifdef WITH_NEXT_FRAMEWORK
459/* On Darwin/MacOSX a shared library or framework has no access to
460** environ directly, we must obtain it with _NSGetEnviron().
461*/
462#include <crt_externs.h>
463static char **environ;
464#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000465extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000466#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000467
Barry Warsaw53699e91996-12-10 23:23:01 +0000468static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000469convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000471 PyObject *d;
472 char **e;
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000473#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +0000474 APIRET rc;
475 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
476#endif
477 d = PyDict_New();
478 if (d == NULL)
479 return NULL;
480#ifdef WITH_NEXT_FRAMEWORK
481 if (environ == NULL)
482 environ = *_NSGetEnviron();
483#endif
484 if (environ == NULL)
485 return d;
486 /* This part ignores errors */
487 for (e = environ; *e != NULL; e++) {
488 PyObject *k;
489 PyObject *v;
490 char *p = strchr(*e, '=');
491 if (p == NULL)
492 continue;
493 k = PyString_FromStringAndSize(*e, (int)(p-*e));
494 if (k == NULL) {
495 PyErr_Clear();
496 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000497 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000498 v = PyString_FromString(p+1);
499 if (v == NULL) {
500 PyErr_Clear();
501 Py_DECREF(k);
502 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503 }
Victor Stinnerd6f85422010-05-05 23:33:33 +0000504 if (PyDict_GetItem(d, k) == NULL) {
505 if (PyDict_SetItem(d, k, v) != 0)
506 PyErr_Clear();
507 }
508 Py_DECREF(k);
509 Py_DECREF(v);
510 }
511#if defined(PYOS_OS2)
512 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
513 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
514 PyObject *v = PyString_FromString(buffer);
515 PyDict_SetItemString(d, "BEGINLIBPATH", v);
516 Py_DECREF(v);
517 }
518 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
519 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
520 PyObject *v = PyString_FromString(buffer);
521 PyDict_SetItemString(d, "ENDLIBPATH", v);
522 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000523 }
524#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +0000525 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000526}
527
528
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529/* Set a POSIX-specific error from errno, and return NULL */
530
Barry Warsawd58d7641998-07-23 16:14:40 +0000531static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000532posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000533{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000534 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000535}
Barry Warsawd58d7641998-07-23 16:14:40 +0000536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000537posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000538{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000539 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000540}
541
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000542#ifdef MS_WINDOWS
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000543static PyObject *
544posix_error_with_unicode_filename(Py_UNICODE* name)
545{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000546 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000547}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000548#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549
550
Mark Hammondef8b6542001-05-13 08:04:26 +0000551static PyObject *
552posix_error_with_allocated_filename(char* name)
553{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000554 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
555 PyMem_Free(name);
556 return rc;
Mark Hammondef8b6542001-05-13 08:04:26 +0000557}
558
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000559#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000560static PyObject *
561win32_error(char* function, char* filename)
562{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000563 /* XXX We should pass the function name along in the future.
564 (_winreg.c also wants to pass the function name.)
565 This would however require an additional param to the
566 Windows error object, which is non-trivial.
567 */
568 errno = GetLastError();
569 if (filename)
570 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
571 else
572 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000573}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000574
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000575static PyObject *
576win32_error_unicode(char* function, Py_UNICODE* filename)
577{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000578 /* XXX - see win32_error for comments on 'function' */
579 errno = GetLastError();
580 if (filename)
581 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
582 else
583 return PyErr_SetFromWindowsErr(errno);
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000584}
585
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000586static int
Hirokazu Yamamotoa0fdd722008-08-17 09:19:52 +0000587convert_to_unicode(PyObject **param)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000588{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000589 if (PyUnicode_CheckExact(*param))
590 Py_INCREF(*param);
591 else if (PyUnicode_Check(*param))
592 /* For a Unicode subtype that's not a Unicode object,
593 return a true Unicode object with the same data. */
594 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
595 PyUnicode_GET_SIZE(*param));
596 else
597 *param = PyUnicode_FromEncodedObject(*param,
598 Py_FileSystemDefaultEncoding,
599 "strict");
600 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000601}
602
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000603#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604
Guido van Rossumd48f2521997-12-05 22:19:34 +0000605#if defined(PYOS_OS2)
606/**********************************************************************
607 * Helper Function to Trim and Format OS/2 Messages
608 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000609static void
Guido van Rossumd48f2521997-12-05 22:19:34 +0000610os2_formatmsg(char *msgbuf, int msglen, char *reason)
611{
612 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
613
614 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
Victor Stinner862490a2010-05-06 00:03:44 +0000615 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
Guido van Rossumd48f2521997-12-05 22:19:34 +0000616
Victor Stinner862490a2010-05-06 00:03:44 +0000617 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
618 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000619 }
620
621 /* Add Optional Reason Text */
622 if (reason) {
623 strcat(msgbuf, " : ");
624 strcat(msgbuf, reason);
625 }
626}
627
628/**********************************************************************
629 * Decode an OS/2 Operating System Error Code
630 *
631 * A convenience function to lookup an OS/2 error code and return a
632 * text message we can use to raise a Python exception.
633 *
634 * Notes:
635 * The messages for errors returned from the OS/2 kernel reside in
636 * the file OSO001.MSG in the \OS2 directory hierarchy.
637 *
638 **********************************************************************/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000639static char *
Guido van Rossumd48f2521997-12-05 22:19:34 +0000640os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
641{
642 APIRET rc;
643 ULONG msglen;
644
645 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
646 Py_BEGIN_ALLOW_THREADS
647 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
648 errorcode, "oso001.msg", &msglen);
649 Py_END_ALLOW_THREADS
650
651 if (rc == NO_ERROR)
652 os2_formatmsg(msgbuf, msglen, reason);
653 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000654 PyOS_snprintf(msgbuf, msgbuflen,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000655 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000656
657 return msgbuf;
658}
659
660/* Set an OS/2-specific error and return NULL. OS/2 kernel
661 errors are not in a global variable e.g. 'errno' nor are
662 they congruent with posix error numbers. */
663
Victor Stinnerd6f85422010-05-05 23:33:33 +0000664static PyObject *
665os2_error(int code)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000666{
667 char text[1024];
668 PyObject *v;
669
670 os2_strerror(text, sizeof(text), code, "");
671
672 v = Py_BuildValue("(is)", code, text);
673 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000674 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000675 Py_DECREF(v);
676 }
677 return NULL; /* Signal to Python that an Exception is Pending */
678}
679
680#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681
682/* POSIX generic methods */
683
Barry Warsaw53699e91996-12-10 23:23:01 +0000684static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000685posix_fildes(PyObject *fdobj, int (*func)(int))
686{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000687 int fd;
688 int res;
689 fd = PyObject_AsFileDescriptor(fdobj);
690 if (fd < 0)
691 return NULL;
692 if (!_PyVerify_fd(fd))
693 return posix_error();
694 Py_BEGIN_ALLOW_THREADS
695 res = (*func)(fd);
696 Py_END_ALLOW_THREADS
697 if (res < 0)
698 return posix_error();
699 Py_INCREF(Py_None);
700 return Py_None;
Fred Drake4d1e64b2002-04-15 19:40:07 +0000701}
Guido van Rossum21142a01999-01-08 21:05:37 +0000702
703static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000704posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000706 char *path1 = NULL;
707 int res;
708 if (!PyArg_ParseTuple(args, format,
709 Py_FileSystemDefaultEncoding, &path1))
710 return NULL;
711 Py_BEGIN_ALLOW_THREADS
712 res = (*func)(path1);
713 Py_END_ALLOW_THREADS
714 if (res < 0)
715 return posix_error_with_allocated_filename(path1);
716 PyMem_Free(path1);
717 Py_INCREF(Py_None);
718 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000719}
720
Barry Warsaw53699e91996-12-10 23:23:01 +0000721static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000722posix_2str(PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +0000723 char *format,
724 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000726 char *path1 = NULL, *path2 = NULL;
727 int res;
728 if (!PyArg_ParseTuple(args, format,
729 Py_FileSystemDefaultEncoding, &path1,
730 Py_FileSystemDefaultEncoding, &path2))
731 return NULL;
732 Py_BEGIN_ALLOW_THREADS
733 res = (*func)(path1, path2);
734 Py_END_ALLOW_THREADS
735 PyMem_Free(path1);
736 PyMem_Free(path2);
737 if (res != 0)
738 /* XXX how to report both path1 and path2??? */
739 return posix_error();
740 Py_INCREF(Py_None);
741 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742}
743
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +0000744#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000745static PyObject*
Victor Stinnerd6f85422010-05-05 23:33:33 +0000746win32_1str(PyObject* args, char* func,
747 char* format, BOOL (__stdcall *funcA)(LPCSTR),
748 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000749{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000750 PyObject *uni;
751 char *ansi;
752 BOOL result;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +0000753
Victor Stinnerd6f85422010-05-05 23:33:33 +0000754 if (!PyArg_ParseTuple(args, wformat, &uni))
755 PyErr_Clear();
756 else {
757 Py_BEGIN_ALLOW_THREADS
758 result = funcW(PyUnicode_AsUnicode(uni));
759 Py_END_ALLOW_THREADS
760 if (!result)
761 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
762 Py_INCREF(Py_None);
763 return Py_None;
764 }
765 if (!PyArg_ParseTuple(args, format, &ansi))
766 return NULL;
767 Py_BEGIN_ALLOW_THREADS
768 result = funcA(ansi);
769 Py_END_ALLOW_THREADS
770 if (!result)
771 return win32_error(func, ansi);
772 Py_INCREF(Py_None);
773 return Py_None;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000774
775}
776
777/* This is a reimplementation of the C library's chdir function,
778 but one that produces Win32 errors instead of DOS error codes.
779 chdir is essentially a wrapper around SetCurrentDirectory; however,
780 it also needs to set "magic" environment variables indicating
781 the per-drive current directory, which are of the form =<drive>: */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000782static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000783win32_chdir(LPCSTR path)
784{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000785 char new_path[MAX_PATH+1];
786 int result;
787 char env[4] = "=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000788
Victor Stinnerd6f85422010-05-05 23:33:33 +0000789 if(!SetCurrentDirectoryA(path))
790 return FALSE;
791 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
792 if (!result)
793 return FALSE;
794 /* In the ANSI API, there should not be any paths longer
795 than MAX_PATH. */
796 assert(result <= MAX_PATH+1);
797 if (strncmp(new_path, "\\\\", 2) == 0 ||
798 strncmp(new_path, "//", 2) == 0)
799 /* UNC path, nothing to do. */
800 return TRUE;
801 env[1] = new_path[0];
802 return SetEnvironmentVariableA(env, new_path);
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000803}
804
805/* The Unicode version differs from the ANSI version
806 since the current directory might exceed MAX_PATH characters */
Hirokazu Yamamoto61376402008-10-16 06:25:25 +0000807static BOOL __stdcall
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000808win32_wchdir(LPCWSTR path)
809{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000810 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
811 int result;
812 wchar_t env[4] = L"=x:";
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000813
Victor Stinnerd6f85422010-05-05 23:33:33 +0000814 if(!SetCurrentDirectoryW(path))
815 return FALSE;
816 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
817 if (!result)
818 return FALSE;
819 if (result > MAX_PATH+1) {
820 new_path = malloc(result * sizeof(wchar_t));
821 if (!new_path) {
822 SetLastError(ERROR_OUTOFMEMORY);
823 return FALSE;
824 }
825 result = GetCurrentDirectoryW(result, new_path);
826 if (!result) {
827 free(new_path);
828 return FALSE;
829 }
830 }
831 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
832 wcsncmp(new_path, L"//", 2) == 0)
833 /* UNC path, nothing to do. */
834 return TRUE;
835 env[1] = new_path[0];
836 result = SetEnvironmentVariableW(env, new_path);
837 if (new_path != _new_path)
838 free(new_path);
839 return result;
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000840}
841#endif
842
Martin v. Löwis14694662006-02-03 12:54:16 +0000843#ifdef MS_WINDOWS
844/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
845 - time stamps are restricted to second resolution
846 - file modification times suffer from forth-and-back conversions between
847 UTC and local time
848 Therefore, we implement our own stat, based on the Win32 API directly.
849*/
Victor Stinnerd6f85422010-05-05 23:33:33 +0000850#define HAVE_STAT_NSEC 1
Martin v. Löwis14694662006-02-03 12:54:16 +0000851
852struct win32_stat{
853 int st_dev;
854 __int64 st_ino;
855 unsigned short st_mode;
856 int st_nlink;
857 int st_uid;
858 int st_gid;
859 int st_rdev;
860 __int64 st_size;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000861 time_t st_atime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000862 int st_atime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000863 time_t st_mtime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000864 int st_mtime_nsec;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000865 time_t st_ctime;
Martin v. Löwis14694662006-02-03 12:54:16 +0000866 int st_ctime_nsec;
867};
868
869static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
870
871static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000872FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
Martin v. Löwis14694662006-02-03 12:54:16 +0000873{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000874 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
875 /* Cannot simply cast and dereference in_ptr,
876 since it might not be aligned properly */
877 __int64 in;
878 memcpy(&in, in_ptr, sizeof(in));
879 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000880 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
Martin v. Löwis14694662006-02-03 12:54:16 +0000881}
882
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000883static void
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +0000884time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000885{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000886 /* XXX endianness */
887 __int64 out;
888 out = time_in + secs_between_epochs;
889 out = out * 10000000 + nsec_in / 100;
890 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000891}
892
Martin v. Löwis14694662006-02-03 12:54:16 +0000893/* Below, we *know* that ugo+r is 0444 */
894#if _S_IREAD != 0400
895#error Unsupported C library
896#endif
897static int
898attributes_to_mode(DWORD attr)
899{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000900 int m = 0;
901 if (attr & FILE_ATTRIBUTE_DIRECTORY)
902 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
903 else
904 m |= _S_IFREG;
905 if (attr & FILE_ATTRIBUTE_READONLY)
906 m |= 0444;
907 else
908 m |= 0666;
909 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000910}
911
912static int
913attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
914{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000915 memset(result, 0, sizeof(*result));
916 result->st_mode = attributes_to_mode(info->dwFileAttributes);
917 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
918 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
919 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
920 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000921
Victor Stinnerd6f85422010-05-05 23:33:33 +0000922 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000923}
924
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000925static BOOL
926attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
927{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000928 HANDLE hFindFile;
929 WIN32_FIND_DATAA FileData;
930 hFindFile = FindFirstFileA(pszFile, &FileData);
931 if (hFindFile == INVALID_HANDLE_VALUE)
932 return FALSE;
933 FindClose(hFindFile);
934 pfad->dwFileAttributes = FileData.dwFileAttributes;
935 pfad->ftCreationTime = FileData.ftCreationTime;
936 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
937 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
938 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
939 pfad->nFileSizeLow = FileData.nFileSizeLow;
940 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000941}
942
943static BOOL
944attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
945{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000946 HANDLE hFindFile;
947 WIN32_FIND_DATAW FileData;
948 hFindFile = FindFirstFileW(pszFile, &FileData);
949 if (hFindFile == INVALID_HANDLE_VALUE)
950 return FALSE;
951 FindClose(hFindFile);
952 pfad->dwFileAttributes = FileData.dwFileAttributes;
953 pfad->ftCreationTime = FileData.ftCreationTime;
954 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
955 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
956 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
957 pfad->nFileSizeLow = FileData.nFileSizeLow;
958 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000959}
960
Victor Stinnerd6f85422010-05-05 23:33:33 +0000961static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000962win32_stat(const char* path, struct win32_stat *result)
963{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000964 WIN32_FILE_ATTRIBUTE_DATA info;
965 int code;
966 char *dot;
967 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
968 if (GetLastError() != ERROR_SHARING_VIOLATION) {
969 /* Protocol violation: we explicitly clear errno, instead of
970 setting it to a POSIX error. Callers should use GetLastError. */
971 errno = 0;
972 return -1;
973 } else {
974 /* Could not get attributes on open file. Fall back to
975 reading the directory. */
976 if (!attributes_from_dir(path, &info)) {
977 /* Very strange. This should not fail now */
978 errno = 0;
979 return -1;
980 }
981 }
982 }
983 code = attribute_data_to_stat(&info, result);
984 if (code != 0)
985 return code;
986 /* Set S_IFEXEC if it is an .exe, .bat, ... */
987 dot = strrchr(path, '.');
988 if (dot) {
989 if (stricmp(dot, ".bat") == 0 ||
990 stricmp(dot, ".cmd") == 0 ||
991 stricmp(dot, ".exe") == 0 ||
992 stricmp(dot, ".com") == 0)
993 result->st_mode |= 0111;
994 }
995 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +0000996}
997
Victor Stinnerd6f85422010-05-05 23:33:33 +0000998static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000999win32_wstat(const wchar_t* path, struct win32_stat *result)
1000{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001001 int code;
1002 const wchar_t *dot;
1003 WIN32_FILE_ATTRIBUTE_DATA info;
1004 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1005 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1006 /* Protocol violation: we explicitly clear errno, instead of
1007 setting it to a POSIX error. Callers should use GetLastError. */
1008 errno = 0;
1009 return -1;
1010 } else {
1011 /* Could not get attributes on open file. Fall back to
1012 reading the directory. */
1013 if (!attributes_from_dir_w(path, &info)) {
1014 /* Very strange. This should not fail now */
1015 errno = 0;
1016 return -1;
1017 }
1018 }
1019 }
1020 code = attribute_data_to_stat(&info, result);
1021 if (code < 0)
1022 return code;
1023 /* Set IFEXEC if it is an .exe, .bat, ... */
1024 dot = wcsrchr(path, '.');
1025 if (dot) {
1026 if (_wcsicmp(dot, L".bat") == 0 ||
1027 _wcsicmp(dot, L".cmd") == 0 ||
1028 _wcsicmp(dot, L".exe") == 0 ||
1029 _wcsicmp(dot, L".com") == 0)
1030 result->st_mode |= 0111;
1031 }
1032 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001033}
1034
1035static int
1036win32_fstat(int file_number, struct win32_stat *result)
1037{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001038 BY_HANDLE_FILE_INFORMATION info;
1039 HANDLE h;
1040 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001041
Victor Stinnerd6f85422010-05-05 23:33:33 +00001042 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001043
Victor Stinnerd6f85422010-05-05 23:33:33 +00001044 /* Protocol violation: we explicitly clear errno, instead of
1045 setting it to a POSIX error. Callers should use GetLastError. */
1046 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001047
Victor Stinnerd6f85422010-05-05 23:33:33 +00001048 if (h == INVALID_HANDLE_VALUE) {
1049 /* This is really a C library error (invalid file handle).
1050 We set the Win32 error to the closes one matching. */
1051 SetLastError(ERROR_INVALID_HANDLE);
1052 return -1;
1053 }
1054 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001055
Victor Stinnerd6f85422010-05-05 23:33:33 +00001056 type = GetFileType(h);
1057 if (type == FILE_TYPE_UNKNOWN) {
1058 DWORD error = GetLastError();
1059 if (error != 0) {
1060 return -1;
1061 }
1062 /* else: valid but unknown file */
1063 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001064
Victor Stinnerd6f85422010-05-05 23:33:33 +00001065 if (type != FILE_TYPE_DISK) {
1066 if (type == FILE_TYPE_CHAR)
1067 result->st_mode = _S_IFCHR;
1068 else if (type == FILE_TYPE_PIPE)
1069 result->st_mode = _S_IFIFO;
1070 return 0;
1071 }
1072
1073 if (!GetFileInformationByHandle(h, &info)) {
1074 return -1;
1075 }
1076
1077 /* similar to stat() */
1078 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1079 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1080 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1081 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1082 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1083 /* specific to fstat() */
1084 result->st_nlink = info.nNumberOfLinks;
1085 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1086 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001087}
1088
1089#endif /* MS_WINDOWS */
1090
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001091PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001092"stat_result: Result from stat or lstat.\n\n\
1093This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001094 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001095or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1096\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001097Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1098or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001099\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001100See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001101
1102static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001103 {"st_mode", "protection bits"},
1104 {"st_ino", "inode"},
1105 {"st_dev", "device"},
1106 {"st_nlink", "number of hard links"},
1107 {"st_uid", "user ID of owner"},
1108 {"st_gid", "group ID of owner"},
1109 {"st_size", "total size, in bytes"},
1110 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1111 {NULL, "integer time of last access"},
1112 {NULL, "integer time of last modification"},
1113 {NULL, "integer time of last change"},
1114 {"st_atime", "time of last access"},
1115 {"st_mtime", "time of last modification"},
1116 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001117#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001118 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001120#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001121 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001122#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001123#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001124 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001125#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001126#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001127 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001128#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001129#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001130 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001131#endif
1132#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001133 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001134#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001135 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001136};
1137
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001138#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001139#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001140#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001141#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001142#endif
1143
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001144#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001145#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1146#else
1147#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1148#endif
1149
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001150#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001151#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1152#else
1153#define ST_RDEV_IDX ST_BLOCKS_IDX
1154#endif
1155
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001156#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1157#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1158#else
1159#define ST_FLAGS_IDX ST_RDEV_IDX
1160#endif
1161
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001162#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001163#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001164#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001165#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001166#endif
1167
1168#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1169#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1170#else
1171#define ST_BIRTHTIME_IDX ST_GEN_IDX
1172#endif
1173
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001174static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001175 "stat_result", /* name */
1176 stat_result__doc__, /* doc */
1177 stat_result_fields,
1178 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001179};
1180
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001181PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001182"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1183This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001184 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001185or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001186\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001187See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001188
1189static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001190 {"f_bsize", },
1191 {"f_frsize", },
1192 {"f_blocks", },
1193 {"f_bfree", },
1194 {"f_bavail", },
1195 {"f_files", },
1196 {"f_ffree", },
1197 {"f_favail", },
1198 {"f_flag", },
1199 {"f_namemax",},
1200 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001201};
1202
1203static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001204 "statvfs_result", /* name */
1205 statvfs_result__doc__, /* doc */
1206 statvfs_result_fields,
1207 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001208};
1209
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001210static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001211static PyTypeObject StatResultType;
1212static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001213static newfunc structseq_new;
1214
1215static PyObject *
1216statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1217{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001218 PyStructSequence *result;
1219 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001220
Victor Stinnerd6f85422010-05-05 23:33:33 +00001221 result = (PyStructSequence*)structseq_new(type, args, kwds);
1222 if (!result)
1223 return NULL;
1224 /* If we have been initialized from a tuple,
1225 st_?time might be set to None. Initialize it
1226 from the int slots. */
1227 for (i = 7; i <= 9; i++) {
1228 if (result->ob_item[i+3] == Py_None) {
1229 Py_DECREF(Py_None);
1230 Py_INCREF(result->ob_item[i]);
1231 result->ob_item[i+3] = result->ob_item[i];
1232 }
1233 }
1234 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001235}
1236
1237
1238
1239/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001240static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001241
1242PyDoc_STRVAR(stat_float_times__doc__,
1243"stat_float_times([newval]) -> oldval\n\n\
1244Determine whether os.[lf]stat represents time stamps as float objects.\n\
1245If newval is True, future calls to stat() return floats, if it is False,\n\
1246future calls return ints. \n\
1247If newval is omitted, return the current setting.\n");
1248
1249static PyObject*
1250stat_float_times(PyObject* self, PyObject *args)
1251{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001252 int newval = -1;
1253 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1254 return NULL;
1255 if (newval == -1)
1256 /* Return old value */
1257 return PyBool_FromLong(_stat_float_times);
1258 _stat_float_times = newval;
1259 Py_INCREF(Py_None);
1260 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001261}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001262
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001263static void
1264fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1265{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001266 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001267#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001268 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001269#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001270 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001271#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001272 if (!ival)
1273 return;
1274 if (_stat_float_times) {
1275 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1276 } else {
1277 fval = ival;
1278 Py_INCREF(fval);
1279 }
1280 PyStructSequence_SET_ITEM(v, index, ival);
1281 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001282}
1283
Tim Peters5aa91602002-01-30 05:46:57 +00001284/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001285 (used by posix_stat() and posix_fstat()) */
1286static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001287_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001288{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001289 unsigned long ansec, mnsec, cnsec;
1290 PyObject *v = PyStructSequence_New(&StatResultType);
1291 if (v == NULL)
1292 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001293
Victor Stinnerd6f85422010-05-05 23:33:33 +00001294 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001295#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001296 PyStructSequence_SET_ITEM(v, 1,
1297 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001298#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001299 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001300#endif
1301#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001302 PyStructSequence_SET_ITEM(v, 2,
1303 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001304#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001305 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001306#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001307 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1308 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1309 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001310#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001311 PyStructSequence_SET_ITEM(v, 6,
1312 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001313#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001314 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001315#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001316
Martin v. Löwis14694662006-02-03 12:54:16 +00001317#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001318 ansec = st->st_atim.tv_nsec;
1319 mnsec = st->st_mtim.tv_nsec;
1320 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001321#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001322 ansec = st->st_atimespec.tv_nsec;
1323 mnsec = st->st_mtimespec.tv_nsec;
1324 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001325#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001326 ansec = st->st_atime_nsec;
1327 mnsec = st->st_mtime_nsec;
1328 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001329#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001330 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001331#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001332 fill_time(v, 7, st->st_atime, ansec);
1333 fill_time(v, 8, st->st_mtime, mnsec);
1334 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001335
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001336#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001337 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1338 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001339#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001340#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001341 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1342 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001343#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001344#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001345 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1346 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001347#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001348#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001349 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1350 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001351#endif
1352#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001353 {
1354 PyObject *val;
1355 unsigned long bsec,bnsec;
1356 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001357#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001358 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001359#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001360 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001361#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001362 if (_stat_float_times) {
1363 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1364 } else {
1365 val = PyInt_FromLong((long)bsec);
1366 }
1367 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1368 val);
1369 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001370#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001371#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001372 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1373 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001374#endif
Fred Drake699f3522000-06-29 21:12:41 +00001375
Victor Stinnerd6f85422010-05-05 23:33:33 +00001376 if (PyErr_Occurred()) {
1377 Py_DECREF(v);
1378 return NULL;
1379 }
Fred Drake699f3522000-06-29 21:12:41 +00001380
Victor Stinnerd6f85422010-05-05 23:33:33 +00001381 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001382}
1383
Martin v. Löwisd8948722004-06-02 09:57:56 +00001384#ifdef MS_WINDOWS
1385
1386/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1387 where / can be used in place of \ and the trailing slash is optional.
1388 Both SERVER and SHARE must have at least one character.
1389*/
1390
1391#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1392#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001393#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001394#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001395#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001396
Tim Peters4ad82172004-08-30 17:02:04 +00001397static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001398IsUNCRootA(char *path, int pathlen)
1399{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001400 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001401
Victor Stinnerd6f85422010-05-05 23:33:33 +00001402 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001403
Victor Stinnerd6f85422010-05-05 23:33:33 +00001404 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1405 /* minimum UNCRoot is \\x\y */
1406 return FALSE;
1407 for (i = 2; i < pathlen ; i++)
1408 if (ISSLASH(path[i])) break;
1409 if (i == 2 || i == pathlen)
1410 /* do not allow \\\SHARE or \\SERVER */
1411 return FALSE;
1412 share = i+1;
1413 for (i = share; i < pathlen; i++)
1414 if (ISSLASH(path[i])) break;
1415 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001416
Victor Stinnerd6f85422010-05-05 23:33:33 +00001417 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001418}
1419
Tim Peters4ad82172004-08-30 17:02:04 +00001420static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001421IsUNCRootW(Py_UNICODE *path, int pathlen)
1422{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001423 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001424
Victor Stinnerd6f85422010-05-05 23:33:33 +00001425 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001426
Victor Stinnerd6f85422010-05-05 23:33:33 +00001427 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1428 /* minimum UNCRoot is \\x\y */
1429 return FALSE;
1430 for (i = 2; i < pathlen ; i++)
1431 if (ISSLASH(path[i])) break;
1432 if (i == 2 || i == pathlen)
1433 /* do not allow \\\SHARE or \\SERVER */
1434 return FALSE;
1435 share = i+1;
1436 for (i = share; i < pathlen; i++)
1437 if (ISSLASH(path[i])) break;
1438 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001439
Victor Stinnerd6f85422010-05-05 23:33:33 +00001440 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001441}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001442#endif /* MS_WINDOWS */
1443
Barry Warsaw53699e91996-12-10 23:23:01 +00001444static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001445posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001446 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001447#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001448 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001449#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001450 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001451#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001452 char *wformat,
1453 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001454{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001455 STRUCT_STAT st;
1456 char *path = NULL; /* pass this to stat; do not free() it */
1457 char *pathfree = NULL; /* this memory must be free'd */
1458 int res;
1459 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001460
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001461#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001462 PyUnicodeObject *po;
1463 if (PyArg_ParseTuple(args, wformat, &po)) {
1464 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001465
Victor Stinnerd6f85422010-05-05 23:33:33 +00001466 Py_BEGIN_ALLOW_THREADS
1467 /* PyUnicode_AS_UNICODE result OK without
1468 thread lock as it is a simple dereference. */
1469 res = wstatfunc(wpath, &st);
1470 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001471
Victor Stinnerd6f85422010-05-05 23:33:33 +00001472 if (res != 0)
1473 return win32_error_unicode("stat", wpath);
1474 return _pystat_fromstructstat(&st);
1475 }
1476 /* Drop the argument parsing error as narrow strings
1477 are also valid. */
1478 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001479#endif
1480
Victor Stinnerd6f85422010-05-05 23:33:33 +00001481 if (!PyArg_ParseTuple(args, format,
1482 Py_FileSystemDefaultEncoding, &path))
1483 return NULL;
1484 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001485
Victor Stinnerd6f85422010-05-05 23:33:33 +00001486 Py_BEGIN_ALLOW_THREADS
1487 res = (*statfunc)(path, &st);
1488 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001489
Victor Stinnerd6f85422010-05-05 23:33:33 +00001490 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001491#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001492 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001493#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001494 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001495#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001496 }
1497 else
1498 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001499
Victor Stinnerd6f85422010-05-05 23:33:33 +00001500 PyMem_Free(pathfree);
1501 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502}
1503
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001504/* POSIX methods */
1505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001507"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001508Use the real uid/gid to test for access to a path. Note that most\n\
1509operations will use the effective uid/gid, therefore this routine can\n\
1510be used in a suid/sgid environment to test if the invoking user has the\n\
1511specified access to the path. The mode argument can be F_OK to test\n\
1512existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001513
1514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001515posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001516{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001517 char *path;
1518 int mode;
1519
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001520#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001521 DWORD attr;
1522 PyUnicodeObject *po;
1523 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1524 Py_BEGIN_ALLOW_THREADS
1525 /* PyUnicode_AS_UNICODE OK without thread lock as
1526 it is a simple dereference. */
1527 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1528 Py_END_ALLOW_THREADS
1529 goto finish;
1530 }
1531 /* Drop the argument parsing error as narrow strings
1532 are also valid. */
1533 PyErr_Clear();
1534 if (!PyArg_ParseTuple(args, "eti:access",
1535 Py_FileSystemDefaultEncoding, &path, &mode))
1536 return NULL;
1537 Py_BEGIN_ALLOW_THREADS
1538 attr = GetFileAttributesA(path);
1539 Py_END_ALLOW_THREADS
1540 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001541finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001542 if (attr == 0xFFFFFFFF)
1543 /* File does not exist, or cannot read attributes */
1544 return PyBool_FromLong(0);
1545 /* Access is possible if either write access wasn't requested, or
1546 the file isn't read-only, or if it's a directory, as there are
1547 no read-only directories on Windows. */
1548 return PyBool_FromLong(!(mode & 2)
1549 || !(attr & FILE_ATTRIBUTE_READONLY)
1550 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001551#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001552 int res;
1553 if (!PyArg_ParseTuple(args, "eti:access",
1554 Py_FileSystemDefaultEncoding, &path, &mode))
1555 return NULL;
1556 Py_BEGIN_ALLOW_THREADS
1557 res = access(path, mode);
1558 Py_END_ALLOW_THREADS
1559 PyMem_Free(path);
1560 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001561#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001562}
1563
Guido van Rossumd371ff11999-01-25 16:12:23 +00001564#ifndef F_OK
1565#define F_OK 0
1566#endif
1567#ifndef R_OK
1568#define R_OK 4
1569#endif
1570#ifndef W_OK
1571#define W_OK 2
1572#endif
1573#ifndef X_OK
1574#define X_OK 1
1575#endif
1576
1577#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001578PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001579"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001580Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001581
1582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001583posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001584{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001585 int id;
1586 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001587
Victor Stinnerd6f85422010-05-05 23:33:33 +00001588 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1589 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001590
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001591#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001592 /* file descriptor 0 only, the default input device (stdin) */
1593 if (id == 0) {
1594 ret = ttyname();
1595 }
1596 else {
1597 ret = NULL;
1598 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001599#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001600 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001601#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001602 if (ret == NULL)
1603 return posix_error();
1604 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001605}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001606#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001607
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001608#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001609PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001610"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001611Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001612
1613static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001614posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001615{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001616 char *ret;
1617 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001618
Greg Wardb48bc172000-03-01 21:51:56 +00001619#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001620 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001621#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001622 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001623#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001624 if (ret == NULL)
1625 return posix_error();
1626 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001627}
1628#endif
1629
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001631"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001633
Barry Warsaw53699e91996-12-10 23:23:01 +00001634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001635posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001636{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001637#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001638 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001639#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001640 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001641#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001642 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001643#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001644 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001645#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001646}
1647
Fred Drake4d1e64b2002-04-15 19:40:07 +00001648#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001649PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001650"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001651Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001653
1654static PyObject *
1655posix_fchdir(PyObject *self, PyObject *fdobj)
1656{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001657 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001658}
1659#endif /* HAVE_FCHDIR */
1660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001662PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001663"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001664Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001665
Barry Warsaw53699e91996-12-10 23:23:01 +00001666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001667posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001669 char *path = NULL;
1670 int i;
1671 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001672#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001673 DWORD attr;
1674 PyUnicodeObject *po;
1675 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1676 Py_BEGIN_ALLOW_THREADS
1677 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1678 if (attr != 0xFFFFFFFF) {
1679 if (i & _S_IWRITE)
1680 attr &= ~FILE_ATTRIBUTE_READONLY;
1681 else
1682 attr |= FILE_ATTRIBUTE_READONLY;
1683 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1684 }
1685 else
1686 res = 0;
1687 Py_END_ALLOW_THREADS
1688 if (!res)
1689 return win32_error_unicode("chmod",
1690 PyUnicode_AS_UNICODE(po));
1691 Py_INCREF(Py_None);
1692 return Py_None;
1693 }
1694 /* Drop the argument parsing error as narrow strings
1695 are also valid. */
1696 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001697
Victor Stinnerd6f85422010-05-05 23:33:33 +00001698 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1699 &path, &i))
1700 return NULL;
1701 Py_BEGIN_ALLOW_THREADS
1702 attr = GetFileAttributesA(path);
1703 if (attr != 0xFFFFFFFF) {
1704 if (i & _S_IWRITE)
1705 attr &= ~FILE_ATTRIBUTE_READONLY;
1706 else
1707 attr |= FILE_ATTRIBUTE_READONLY;
1708 res = SetFileAttributesA(path, attr);
1709 }
1710 else
1711 res = 0;
1712 Py_END_ALLOW_THREADS
1713 if (!res) {
1714 win32_error("chmod", path);
1715 PyMem_Free(path);
1716 return NULL;
1717 }
1718 PyMem_Free(path);
1719 Py_INCREF(Py_None);
1720 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001721#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001722 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1723 &path, &i))
1724 return NULL;
1725 Py_BEGIN_ALLOW_THREADS
1726 res = chmod(path, i);
1727 Py_END_ALLOW_THREADS
1728 if (res < 0)
1729 return posix_error_with_allocated_filename(path);
1730 PyMem_Free(path);
1731 Py_INCREF(Py_None);
1732 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001733#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001734}
1735
Christian Heimes36281872007-11-30 21:11:28 +00001736#ifdef HAVE_FCHMOD
1737PyDoc_STRVAR(posix_fchmod__doc__,
1738"fchmod(fd, mode)\n\n\
1739Change the access permissions of the file given by file\n\
1740descriptor fd.");
1741
1742static PyObject *
1743posix_fchmod(PyObject *self, PyObject *args)
1744{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001745 int fd, mode, res;
1746 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1747 return NULL;
1748 Py_BEGIN_ALLOW_THREADS
1749 res = fchmod(fd, mode);
1750 Py_END_ALLOW_THREADS
1751 if (res < 0)
1752 return posix_error();
1753 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001754}
1755#endif /* HAVE_FCHMOD */
1756
1757#ifdef HAVE_LCHMOD
1758PyDoc_STRVAR(posix_lchmod__doc__,
1759"lchmod(path, mode)\n\n\
1760Change the access permissions of a file. If path is a symlink, this\n\
1761affects the link itself rather than the target.");
1762
1763static PyObject *
1764posix_lchmod(PyObject *self, PyObject *args)
1765{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001766 char *path = NULL;
1767 int i;
1768 int res;
1769 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1770 &path, &i))
1771 return NULL;
1772 Py_BEGIN_ALLOW_THREADS
1773 res = lchmod(path, i);
1774 Py_END_ALLOW_THREADS
1775 if (res < 0)
1776 return posix_error_with_allocated_filename(path);
1777 PyMem_Free(path);
1778 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001779}
1780#endif /* HAVE_LCHMOD */
1781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
Martin v. Löwis382abef2007-02-19 10:55:19 +00001783#ifdef HAVE_CHFLAGS
1784PyDoc_STRVAR(posix_chflags__doc__,
1785"chflags(path, flags)\n\n\
1786Set file flags.");
1787
1788static PyObject *
1789posix_chflags(PyObject *self, PyObject *args)
1790{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001791 char *path;
1792 unsigned long flags;
1793 int res;
1794 if (!PyArg_ParseTuple(args, "etk:chflags",
1795 Py_FileSystemDefaultEncoding, &path, &flags))
1796 return NULL;
1797 Py_BEGIN_ALLOW_THREADS
1798 res = chflags(path, flags);
1799 Py_END_ALLOW_THREADS
1800 if (res < 0)
1801 return posix_error_with_allocated_filename(path);
1802 PyMem_Free(path);
1803 Py_INCREF(Py_None);
1804 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001805}
1806#endif /* HAVE_CHFLAGS */
1807
1808#ifdef HAVE_LCHFLAGS
1809PyDoc_STRVAR(posix_lchflags__doc__,
1810"lchflags(path, flags)\n\n\
1811Set file flags.\n\
1812This function will not follow symbolic links.");
1813
1814static PyObject *
1815posix_lchflags(PyObject *self, PyObject *args)
1816{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001817 char *path;
1818 unsigned long flags;
1819 int res;
1820 if (!PyArg_ParseTuple(args, "etk:lchflags",
1821 Py_FileSystemDefaultEncoding, &path, &flags))
1822 return NULL;
1823 Py_BEGIN_ALLOW_THREADS
1824 res = lchflags(path, flags);
1825 Py_END_ALLOW_THREADS
1826 if (res < 0)
1827 return posix_error_with_allocated_filename(path);
1828 PyMem_Free(path);
1829 Py_INCREF(Py_None);
1830 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001831}
1832#endif /* HAVE_LCHFLAGS */
1833
Martin v. Löwis244edc82001-10-04 22:44:26 +00001834#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001838
1839static PyObject *
1840posix_chroot(PyObject *self, PyObject *args)
1841{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001842 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001843}
1844#endif
1845
Guido van Rossum21142a01999-01-08 21:05:37 +00001846#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001847PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001848"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001849force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001850
1851static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001852posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001853{
Stefan Krah93f7a322010-11-26 17:35:50 +00001854 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001855}
1856#endif /* HAVE_FSYNC */
1857
1858#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001859
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001860#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001861extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1862#endif
1863
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001864PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001865"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001866force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001868
1869static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001870posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001871{
Stefan Krah93f7a322010-11-26 17:35:50 +00001872 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001873}
1874#endif /* HAVE_FDATASYNC */
1875
1876
Fredrik Lundh10723342000-07-10 16:38:09 +00001877#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001878PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001879"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001880Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001884{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001885 char *path = NULL;
1886 long uid, gid;
1887 int res;
1888 if (!PyArg_ParseTuple(args, "etll:chown",
1889 Py_FileSystemDefaultEncoding, &path,
1890 &uid, &gid))
1891 return NULL;
1892 Py_BEGIN_ALLOW_THREADS
1893 res = chown(path, (uid_t) uid, (gid_t) gid);
1894 Py_END_ALLOW_THREADS
1895 if (res < 0)
1896 return posix_error_with_allocated_filename(path);
1897 PyMem_Free(path);
1898 Py_INCREF(Py_None);
1899 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001900}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001901#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902
Christian Heimes36281872007-11-30 21:11:28 +00001903#ifdef HAVE_FCHOWN
1904PyDoc_STRVAR(posix_fchown__doc__,
1905"fchown(fd, uid, gid)\n\n\
1906Change the owner and group id of the file given by file descriptor\n\
1907fd to the numeric uid and gid.");
1908
1909static PyObject *
1910posix_fchown(PyObject *self, PyObject *args)
1911{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001912 int fd;
1913 long uid, gid;
1914 int res;
1915 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
1916 return NULL;
1917 Py_BEGIN_ALLOW_THREADS
1918 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1919 Py_END_ALLOW_THREADS
1920 if (res < 0)
1921 return posix_error();
1922 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001923}
1924#endif /* HAVE_FCHOWN */
1925
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001926#ifdef HAVE_LCHOWN
1927PyDoc_STRVAR(posix_lchown__doc__,
1928"lchown(path, uid, gid)\n\n\
1929Change the owner and group id of path to the numeric uid and gid.\n\
1930This function will not follow symbolic links.");
1931
1932static PyObject *
1933posix_lchown(PyObject *self, PyObject *args)
1934{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001935 char *path = NULL;
1936 long uid, gid;
1937 int res;
1938 if (!PyArg_ParseTuple(args, "etll:lchown",
1939 Py_FileSystemDefaultEncoding, &path,
1940 &uid, &gid))
1941 return NULL;
1942 Py_BEGIN_ALLOW_THREADS
1943 res = lchown(path, (uid_t) uid, (gid_t) gid);
1944 Py_END_ALLOW_THREADS
1945 if (res < 0)
1946 return posix_error_with_allocated_filename(path);
1947 PyMem_Free(path);
1948 Py_INCREF(Py_None);
1949 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001950}
1951#endif /* HAVE_LCHOWN */
1952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001953
Guido van Rossum36bc6801995-06-14 22:54:23 +00001954#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001956"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Stefan Krah182ae642010-07-13 19:17:08 +00001959#if (defined(__sun) && defined(__SVR4)) || defined(__OpenBSD__)
1960/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
1961static PyObject *
1962posix_getcwd(PyObject *self, PyObject *noargs)
1963{
1964 char buf[PATH_MAX+2];
1965 char *res;
1966
1967 Py_BEGIN_ALLOW_THREADS
Stefan Krah8cb9f032010-07-13 19:40:00 +00001968 res = getcwd(buf, sizeof buf);
Stefan Krah182ae642010-07-13 19:17:08 +00001969 Py_END_ALLOW_THREADS
1970
1971 if (res == NULL)
1972 return posix_error();
1973
1974 return PyString_FromString(buf);
1975}
1976#else
Barry Warsaw53699e91996-12-10 23:23:01 +00001977static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001978posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001979{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001980 int bufsize_incr = 1024;
1981 int bufsize = 0;
1982 char *tmpbuf = NULL;
1983 char *res = NULL;
1984 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001985
Victor Stinnerd6f85422010-05-05 23:33:33 +00001986 Py_BEGIN_ALLOW_THREADS
1987 do {
1988 bufsize = bufsize + bufsize_incr;
1989 tmpbuf = malloc(bufsize);
1990 if (tmpbuf == NULL) {
1991 break;
1992 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001993#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001994 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001995#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001996 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001997#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00001998
Victor Stinnerd6f85422010-05-05 23:33:33 +00001999 if (res == NULL) {
2000 free(tmpbuf);
2001 }
2002 } while ((res == NULL) && (errno == ERANGE));
2003 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002004
Victor Stinnerd6f85422010-05-05 23:33:33 +00002005 if (res == NULL)
2006 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002007
Victor Stinnerd6f85422010-05-05 23:33:33 +00002008 dynamic_return = PyString_FromString(tmpbuf);
2009 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002010
Victor Stinnerd6f85422010-05-05 23:33:33 +00002011 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002012}
Stefan Krah182ae642010-07-13 19:17:08 +00002013#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002014
Walter Dörwald3b918c32002-11-21 20:18:46 +00002015#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002016PyDoc_STRVAR(posix_getcwdu__doc__,
2017"getcwdu() -> path\n\n\
2018Return a unicode string representing the current working directory.");
2019
2020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002021posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002022{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002023 char buf[1026];
2024 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002025
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002026#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002027 DWORD len;
2028 wchar_t wbuf[1026];
2029 wchar_t *wbuf2 = wbuf;
2030 PyObject *resobj;
2031 Py_BEGIN_ALLOW_THREADS
2032 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2033 /* If the buffer is large enough, len does not include the
2034 terminating \0. If the buffer is too small, len includes
2035 the space needed for the terminator. */
2036 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2037 wbuf2 = malloc(len * sizeof(wchar_t));
2038 if (wbuf2)
2039 len = GetCurrentDirectoryW(len, wbuf2);
2040 }
2041 Py_END_ALLOW_THREADS
2042 if (!wbuf2) {
2043 PyErr_NoMemory();
2044 return NULL;
2045 }
2046 if (!len) {
2047 if (wbuf2 != wbuf) free(wbuf2);
2048 return win32_error("getcwdu", NULL);
2049 }
2050 resobj = PyUnicode_FromWideChar(wbuf2, len);
2051 if (wbuf2 != wbuf) free(wbuf2);
2052 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002053#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002054
Victor Stinnerd6f85422010-05-05 23:33:33 +00002055 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002056#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002057 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002058#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002059 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002060#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002061 Py_END_ALLOW_THREADS
2062 if (res == NULL)
2063 return posix_error();
2064 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002065}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002066#endif /* Py_USING_UNICODE */
2067#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002069
Guido van Rossumb6775db1994-08-01 11:34:53 +00002070#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002072"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Barry Warsaw53699e91996-12-10 23:23:01 +00002075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002076posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002077{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002078 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002083PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002084"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085Return a list containing the names of the entries in the directory.\n\
2086\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002087 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002088\n\
2089The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Barry Warsaw53699e91996-12-10 23:23:01 +00002092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002093posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002095 /* XXX Should redo this putting the (now four) versions of opendir
2096 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002097#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002098
Victor Stinnerd6f85422010-05-05 23:33:33 +00002099 PyObject *d, *v;
2100 HANDLE hFindFile;
2101 BOOL result;
2102 WIN32_FIND_DATA FileData;
2103 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2104 char *bufptr = namebuf;
2105 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106
Victor Stinnerd6f85422010-05-05 23:33:33 +00002107 PyObject *po;
2108 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2109 WIN32_FIND_DATAW wFileData;
2110 Py_UNICODE *wnamebuf;
2111 /* Overallocate for \\*.*\0 */
2112 len = PyUnicode_GET_SIZE(po);
2113 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2114 if (!wnamebuf) {
2115 PyErr_NoMemory();
2116 return NULL;
2117 }
2118 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2119 if (len > 0) {
2120 Py_UNICODE wch = wnamebuf[len-1];
2121 if (wch != L'/' && wch != L'\\' && wch != L':')
2122 wnamebuf[len++] = L'\\';
2123 wcscpy(wnamebuf + len, L"*.*");
2124 }
2125 if ((d = PyList_New(0)) == NULL) {
2126 free(wnamebuf);
2127 return NULL;
2128 }
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002129 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002130 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002131 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002132 if (hFindFile == INVALID_HANDLE_VALUE) {
2133 int error = GetLastError();
2134 if (error == ERROR_FILE_NOT_FOUND) {
2135 free(wnamebuf);
2136 return d;
2137 }
2138 Py_DECREF(d);
2139 win32_error_unicode("FindFirstFileW", wnamebuf);
2140 free(wnamebuf);
2141 return NULL;
2142 }
2143 do {
2144 /* Skip over . and .. */
2145 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2146 wcscmp(wFileData.cFileName, L"..") != 0) {
2147 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2148 if (v == NULL) {
2149 Py_DECREF(d);
2150 d = NULL;
2151 break;
2152 }
2153 if (PyList_Append(d, v) != 0) {
2154 Py_DECREF(v);
2155 Py_DECREF(d);
2156 d = NULL;
2157 break;
2158 }
2159 Py_DECREF(v);
2160 }
2161 Py_BEGIN_ALLOW_THREADS
2162 result = FindNextFileW(hFindFile, &wFileData);
2163 Py_END_ALLOW_THREADS
2164 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2165 it got to the end of the directory. */
2166 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2167 Py_DECREF(d);
2168 win32_error_unicode("FindNextFileW", wnamebuf);
2169 FindClose(hFindFile);
2170 free(wnamebuf);
2171 return NULL;
2172 }
2173 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002174
Victor Stinnerd6f85422010-05-05 23:33:33 +00002175 if (FindClose(hFindFile) == FALSE) {
2176 Py_DECREF(d);
2177 win32_error_unicode("FindClose", wnamebuf);
2178 free(wnamebuf);
2179 return NULL;
2180 }
2181 free(wnamebuf);
2182 return d;
2183 }
2184 /* Drop the argument parsing error as narrow strings
2185 are also valid. */
2186 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002187
Victor Stinnerd6f85422010-05-05 23:33:33 +00002188 if (!PyArg_ParseTuple(args, "et#:listdir",
2189 Py_FileSystemDefaultEncoding, &bufptr, &len))
2190 return NULL;
2191 if (len > 0) {
2192 char ch = namebuf[len-1];
2193 if (ch != SEP && ch != ALTSEP && ch != ':')
2194 namebuf[len++] = '/';
2195 strcpy(namebuf + len, "*.*");
2196 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002197
Victor Stinnerd6f85422010-05-05 23:33:33 +00002198 if ((d = PyList_New(0)) == NULL)
2199 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002200
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002201 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002202 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitrou8cdede42010-08-10 00:04:13 +00002203 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 if (hFindFile == INVALID_HANDLE_VALUE) {
2205 int error = GetLastError();
2206 if (error == ERROR_FILE_NOT_FOUND)
2207 return d;
2208 Py_DECREF(d);
2209 return win32_error("FindFirstFile", namebuf);
2210 }
2211 do {
2212 /* Skip over . and .. */
2213 if (strcmp(FileData.cFileName, ".") != 0 &&
2214 strcmp(FileData.cFileName, "..") != 0) {
2215 v = PyString_FromString(FileData.cFileName);
2216 if (v == NULL) {
2217 Py_DECREF(d);
2218 d = NULL;
2219 break;
2220 }
2221 if (PyList_Append(d, v) != 0) {
2222 Py_DECREF(v);
2223 Py_DECREF(d);
2224 d = NULL;
2225 break;
2226 }
2227 Py_DECREF(v);
2228 }
2229 Py_BEGIN_ALLOW_THREADS
2230 result = FindNextFile(hFindFile, &FileData);
2231 Py_END_ALLOW_THREADS
2232 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2233 it got to the end of the directory. */
2234 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2235 Py_DECREF(d);
2236 win32_error("FindNextFile", namebuf);
2237 FindClose(hFindFile);
2238 return NULL;
2239 }
2240 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002241
Victor Stinnerd6f85422010-05-05 23:33:33 +00002242 if (FindClose(hFindFile) == FALSE) {
2243 Py_DECREF(d);
2244 return win32_error("FindClose", namebuf);
2245 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002246
Victor Stinnerd6f85422010-05-05 23:33:33 +00002247 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002248
Tim Peters0bb44a42000-09-15 07:44:49 +00002249#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002250
2251#ifndef MAX_PATH
2252#define MAX_PATH CCHMAXPATH
2253#endif
2254 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002255 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002256 PyObject *d, *v;
2257 char namebuf[MAX_PATH+5];
2258 HDIR hdir = 1;
2259 ULONG srchcnt = 1;
2260 FILEFINDBUF3 ep;
2261 APIRET rc;
2262
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002263 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002264 return NULL;
2265 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002266 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267 return NULL;
2268 }
2269 strcpy(namebuf, name);
2270 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002271 if (*pt == ALTSEP)
2272 *pt = SEP;
2273 if (namebuf[len-1] != SEP)
2274 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002275 strcpy(namebuf + len, "*.*");
2276
Victor Stinnerd6f85422010-05-05 23:33:33 +00002277 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278 return NULL;
2279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2281 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002283 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2284 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2285 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286
2287 if (rc != NO_ERROR) {
2288 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002289 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290 }
2291
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002293 do {
2294 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002295 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002296 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297
2298 strcpy(namebuf, ep.achName);
2299
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002300 /* Leave Case of Name Alone -- In Native Form */
2301 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002303 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304 if (v == NULL) {
2305 Py_DECREF(d);
2306 d = NULL;
2307 break;
2308 }
2309 if (PyList_Append(d, v) != 0) {
2310 Py_DECREF(v);
2311 Py_DECREF(d);
2312 d = NULL;
2313 break;
2314 }
2315 Py_DECREF(v);
2316 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2317 }
2318
2319 return d;
2320#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002321
Victor Stinnerd6f85422010-05-05 23:33:33 +00002322 char *name = NULL;
2323 PyObject *d, *v;
2324 DIR *dirp;
2325 struct dirent *ep;
2326 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002327
Victor Stinnerd6f85422010-05-05 23:33:33 +00002328 errno = 0;
2329 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2330 arg_is_unicode = 0;
2331 PyErr_Clear();
2332 }
2333 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2334 return NULL;
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002335 Py_BEGIN_ALLOW_THREADS
2336 dirp = opendir(name);
2337 Py_END_ALLOW_THREADS
2338 if (dirp == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002339 return posix_error_with_allocated_filename(name);
2340 }
2341 if ((d = PyList_New(0)) == NULL) {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002342 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002343 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002344 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002345 PyMem_Free(name);
2346 return NULL;
2347 }
2348 for (;;) {
2349 errno = 0;
2350 Py_BEGIN_ALLOW_THREADS
2351 ep = readdir(dirp);
2352 Py_END_ALLOW_THREADS
2353 if (ep == NULL) {
2354 if (errno == 0) {
2355 break;
2356 } else {
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002357 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002358 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002359 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002360 Py_DECREF(d);
2361 return posix_error_with_allocated_filename(name);
2362 }
2363 }
2364 if (ep->d_name[0] == '.' &&
2365 (NAMLEN(ep) == 1 ||
2366 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2367 continue;
2368 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2369 if (v == NULL) {
2370 Py_DECREF(d);
2371 d = NULL;
2372 break;
2373 }
Just van Rossum46c97842003-02-25 21:42:15 +00002374#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002375 if (arg_is_unicode) {
2376 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002377
Victor Stinnerd6f85422010-05-05 23:33:33 +00002378 w = PyUnicode_FromEncodedObject(v,
2379 Py_FileSystemDefaultEncoding,
2380 "strict");
2381 if (w != NULL) {
2382 Py_DECREF(v);
2383 v = w;
2384 }
2385 else {
2386 /* fall back to the original byte string, as
2387 discussed in patch #683592 */
2388 PyErr_Clear();
2389 }
2390 }
Just van Rossum46c97842003-02-25 21:42:15 +00002391#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002392 if (PyList_Append(d, v) != 0) {
2393 Py_DECREF(v);
2394 Py_DECREF(d);
2395 d = NULL;
2396 break;
2397 }
2398 Py_DECREF(v);
2399 }
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002400 Py_BEGIN_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002401 closedir(dirp);
Antoine Pitrou247e2fd2010-09-04 17:27:10 +00002402 Py_END_ALLOW_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002403 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002404
Victor Stinnerd6f85422010-05-05 23:33:33 +00002405 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002406
Tim Peters0bb44a42000-09-15 07:44:49 +00002407#endif /* which OS */
2408} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002409
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002410#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002411/* A helper function for abspath on win32 */
2412static PyObject *
2413posix__getfullpathname(PyObject *self, PyObject *args)
2414{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002415 /* assume encoded strings won't more than double no of chars */
2416 char inbuf[MAX_PATH*2];
2417 char *inbufp = inbuf;
2418 Py_ssize_t insize = sizeof(inbuf);
2419 char outbuf[MAX_PATH*2];
2420 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002421
Victor Stinnerd6f85422010-05-05 23:33:33 +00002422 PyUnicodeObject *po;
2423 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2424 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2425 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2426 Py_UNICODE *wtemp;
2427 DWORD result;
2428 PyObject *v;
2429 result = GetFullPathNameW(wpath,
2430 sizeof(woutbuf)/sizeof(woutbuf[0]),
2431 woutbuf, &wtemp);
2432 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2433 woutbufp = malloc(result * sizeof(Py_UNICODE));
2434 if (!woutbufp)
2435 return PyErr_NoMemory();
2436 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2437 }
2438 if (result)
2439 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2440 else
2441 v = win32_error_unicode("GetFullPathNameW", wpath);
2442 if (woutbufp != woutbuf)
2443 free(woutbufp);
2444 return v;
2445 }
2446 /* Drop the argument parsing error as narrow strings
2447 are also valid. */
2448 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002449
Victor Stinnerd6f85422010-05-05 23:33:33 +00002450 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2451 Py_FileSystemDefaultEncoding, &inbufp,
2452 &insize))
2453 return NULL;
2454 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2455 outbuf, &temp))
2456 return win32_error("GetFullPathName", inbuf);
2457 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2458 return PyUnicode_Decode(outbuf, strlen(outbuf),
2459 Py_FileSystemDefaultEncoding, NULL);
2460 }
2461 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002462} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002463#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002464
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002465PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002466"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002467Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002468
Barry Warsaw53699e91996-12-10 23:23:01 +00002469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002470posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002471{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002472 int res;
2473 char *path = NULL;
2474 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002475
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002476#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002477 PyUnicodeObject *po;
2478 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2479 Py_BEGIN_ALLOW_THREADS
2480 /* PyUnicode_AS_UNICODE OK without thread lock as
2481 it is a simple dereference. */
2482 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2483 Py_END_ALLOW_THREADS
2484 if (!res)
2485 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2486 Py_INCREF(Py_None);
2487 return Py_None;
2488 }
2489 /* Drop the argument parsing error as narrow strings
2490 are also valid. */
2491 PyErr_Clear();
2492 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2493 Py_FileSystemDefaultEncoding, &path, &mode))
2494 return NULL;
2495 Py_BEGIN_ALLOW_THREADS
2496 /* PyUnicode_AS_UNICODE OK without thread lock as
2497 it is a simple dereference. */
2498 res = CreateDirectoryA(path, NULL);
2499 Py_END_ALLOW_THREADS
2500 if (!res) {
2501 win32_error("mkdir", path);
2502 PyMem_Free(path);
2503 return NULL;
2504 }
2505 PyMem_Free(path);
2506 Py_INCREF(Py_None);
2507 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002508#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002509
Victor Stinnerd6f85422010-05-05 23:33:33 +00002510 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2511 Py_FileSystemDefaultEncoding, &path, &mode))
2512 return NULL;
2513 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002514#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002515 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002516#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002517 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002518#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002519 Py_END_ALLOW_THREADS
2520 if (res < 0)
2521 return posix_error_with_allocated_filename(path);
2522 PyMem_Free(path);
2523 Py_INCREF(Py_None);
2524 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002525#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002526}
2527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002528
Neal Norwitz1818ed72006-03-26 00:29:48 +00002529/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2530#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002531#include <sys/resource.h>
2532#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002533
Neal Norwitz1818ed72006-03-26 00:29:48 +00002534
2535#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002537"nice(inc) -> new_priority\n\n\
2538Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002542{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002543 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002544
Victor Stinnerd6f85422010-05-05 23:33:33 +00002545 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2546 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002547
Victor Stinnerd6f85422010-05-05 23:33:33 +00002548 /* There are two flavours of 'nice': one that returns the new
2549 priority (as required by almost all standards out there) and the
2550 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2551 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002552
Victor Stinnerd6f85422010-05-05 23:33:33 +00002553 If we are of the nice family that returns the new priority, we
2554 need to clear errno before the call, and check if errno is filled
2555 before calling posix_error() on a returnvalue of -1, because the
2556 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002557
Victor Stinnerd6f85422010-05-05 23:33:33 +00002558 errno = 0;
2559 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002560#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002561 if (value == 0)
2562 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002563#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002564 if (value == -1 && errno != 0)
2565 /* either nice() or getpriority() returned an error */
2566 return posix_error();
2567 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002568}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002569#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002571PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002572"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002573Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002574
Barry Warsaw53699e91996-12-10 23:23:01 +00002575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002576posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002577{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002578#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002579 PyObject *o1, *o2;
2580 char *p1, *p2;
2581 BOOL result;
2582 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2583 goto error;
2584 if (!convert_to_unicode(&o1))
2585 goto error;
2586 if (!convert_to_unicode(&o2)) {
2587 Py_DECREF(o1);
2588 goto error;
2589 }
2590 Py_BEGIN_ALLOW_THREADS
2591 result = MoveFileW(PyUnicode_AsUnicode(o1),
2592 PyUnicode_AsUnicode(o2));
2593 Py_END_ALLOW_THREADS
2594 Py_DECREF(o1);
2595 Py_DECREF(o2);
2596 if (!result)
2597 return win32_error("rename", NULL);
2598 Py_INCREF(Py_None);
2599 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002600error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002601 PyErr_Clear();
2602 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2603 return NULL;
2604 Py_BEGIN_ALLOW_THREADS
2605 result = MoveFileA(p1, p2);
2606 Py_END_ALLOW_THREADS
2607 if (!result)
2608 return win32_error("rename", NULL);
2609 Py_INCREF(Py_None);
2610 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002611#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002612 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002613#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002614}
2615
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002617PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002618"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002619Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002620
Barry Warsaw53699e91996-12-10 23:23:01 +00002621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002622posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002623{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002624#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002625 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002626#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002627 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002628#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002629}
2630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002631
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002633"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Barry Warsaw53699e91996-12-10 23:23:01 +00002636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002637posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002638{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002639#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002640 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002641#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002642 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002643#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002644}
2645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002646
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002647#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002648PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002649"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002650Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002651
Barry Warsaw53699e91996-12-10 23:23:01 +00002652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002653posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002654{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002655 char *command;
2656 long sts;
2657 if (!PyArg_ParseTuple(args, "s:system", &command))
2658 return NULL;
2659 Py_BEGIN_ALLOW_THREADS
2660 sts = system(command);
2661 Py_END_ALLOW_THREADS
2662 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002663}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002664#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002667PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002668"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002670
Barry Warsaw53699e91996-12-10 23:23:01 +00002671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002672posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002673{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002674 int i;
2675 if (!PyArg_ParseTuple(args, "i:umask", &i))
2676 return NULL;
2677 i = (int)umask(i);
2678 if (i < 0)
2679 return posix_error();
2680 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002681}
2682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002684PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002685"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002686Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002688PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002689"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002690Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002691
Barry Warsaw53699e91996-12-10 23:23:01 +00002692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002693posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002694{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002695#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002696 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002697#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002698 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002699#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002700}
2701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002702
Guido van Rossumb6775db1994-08-01 11:34:53 +00002703#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002705"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002706Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002707
Barry Warsaw53699e91996-12-10 23:23:01 +00002708static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002709posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002710{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002711 struct utsname u;
2712 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002713
Victor Stinnerd6f85422010-05-05 23:33:33 +00002714 Py_BEGIN_ALLOW_THREADS
2715 res = uname(&u);
2716 Py_END_ALLOW_THREADS
2717 if (res < 0)
2718 return posix_error();
2719 return Py_BuildValue("(sssss)",
2720 u.sysname,
2721 u.nodename,
2722 u.release,
2723 u.version,
2724 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002725}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002726#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002727
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002728static int
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002729extract_time(PyObject *t, time_t* sec, long* usec)
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002730{
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002731 time_t intval;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002732 if (PyFloat_Check(t)) {
2733 double tval = PyFloat_AsDouble(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002734 PyObject *intobj = PyNumber_Long(t);
Victor Stinnerd6f85422010-05-05 23:33:33 +00002735 if (!intobj)
2736 return -1;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002737#if SIZEOF_TIME_T > SIZEOF_LONG
2738 intval = PyInt_AsUnsignedLongLongMask(intobj);
2739#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002740 intval = PyInt_AsLong(intobj);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002741#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002742 Py_DECREF(intobj);
2743 if (intval == -1 && PyErr_Occurred())
2744 return -1;
2745 *sec = intval;
2746 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2747 if (*usec < 0)
2748 /* If rounding gave us a negative number,
2749 truncate. */
2750 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002751 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002752 }
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002753#if SIZEOF_TIME_T > SIZEOF_LONG
2754 intval = PyInt_AsUnsignedLongLongMask(t);
2755#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002756 intval = PyInt_AsLong(t);
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002757#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002758 if (intval == -1 && PyErr_Occurred())
2759 return -1;
2760 *sec = intval;
2761 *usec = 0;
2762 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002763}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002765PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002766"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002767utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002768Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002769second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002770
Barry Warsaw53699e91996-12-10 23:23:01 +00002771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002772posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002773{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002774#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002775 PyObject *arg;
2776 PyUnicodeObject *obwpath;
2777 wchar_t *wpath = NULL;
2778 char *apath = NULL;
2779 HANDLE hFile;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002780 time_t atimesec, mtimesec;
2781 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002782 FILETIME atime, mtime;
2783 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002784
Victor Stinnerd6f85422010-05-05 23:33:33 +00002785 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2786 wpath = PyUnicode_AS_UNICODE(obwpath);
2787 Py_BEGIN_ALLOW_THREADS
2788 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2789 NULL, OPEN_EXISTING,
2790 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2791 Py_END_ALLOW_THREADS
2792 if (hFile == INVALID_HANDLE_VALUE)
2793 return win32_error_unicode("utime", wpath);
2794 } else
2795 /* Drop the argument parsing error as narrow strings
2796 are also valid. */
2797 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002798
Victor Stinnerd6f85422010-05-05 23:33:33 +00002799 if (!wpath) {
2800 if (!PyArg_ParseTuple(args, "etO:utime",
2801 Py_FileSystemDefaultEncoding, &apath, &arg))
2802 return NULL;
2803 Py_BEGIN_ALLOW_THREADS
2804 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2805 NULL, OPEN_EXISTING,
2806 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2807 Py_END_ALLOW_THREADS
2808 if (hFile == INVALID_HANDLE_VALUE) {
2809 win32_error("utime", apath);
2810 PyMem_Free(apath);
2811 return NULL;
2812 }
2813 PyMem_Free(apath);
2814 }
2815
2816 if (arg == Py_None) {
2817 SYSTEMTIME now;
2818 GetSystemTime(&now);
2819 if (!SystemTimeToFileTime(&now, &mtime) ||
2820 !SystemTimeToFileTime(&now, &atime)) {
2821 win32_error("utime", NULL);
2822 goto done;
Stefan Krah93f7a322010-11-26 17:35:50 +00002823 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00002824 }
2825 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2826 PyErr_SetString(PyExc_TypeError,
2827 "utime() arg 2 must be a tuple (atime, mtime)");
2828 goto done;
2829 }
2830 else {
2831 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2832 &atimesec, &ausec) == -1)
2833 goto done;
2834 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2835 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2836 &mtimesec, &musec) == -1)
2837 goto done;
2838 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2839 }
2840 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2841 /* Avoid putting the file name into the error here,
2842 as that may confuse the user into believing that
2843 something is wrong with the file, when it also
2844 could be the time stamp that gives a problem. */
2845 win32_error("utime", NULL);
Antoine Pitrou1f1613f2011-01-06 18:30:26 +00002846 goto done;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002847 }
2848 Py_INCREF(Py_None);
2849 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002850done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002851 CloseHandle(hFile);
2852 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002853#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002854
Victor Stinnerd6f85422010-05-05 23:33:33 +00002855 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002856 time_t atime, mtime;
2857 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002858 int res;
2859 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002860
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002861#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002862 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002863#define ATIME buf[0].tv_sec
2864#define MTIME buf[1].tv_sec
2865#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002866/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002867 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002868#define ATIME buf.actime
2869#define MTIME buf.modtime
2870#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002871#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002872 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002873#define ATIME buf[0]
2874#define MTIME buf[1]
2875#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002876#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002877
Mark Hammond817c9292003-12-03 01:22:38 +00002878
Victor Stinnerd6f85422010-05-05 23:33:33 +00002879 if (!PyArg_ParseTuple(args, "etO:utime",
2880 Py_FileSystemDefaultEncoding, &path, &arg))
2881 return NULL;
2882 if (arg == Py_None) {
2883 /* optional time values not given */
2884 Py_BEGIN_ALLOW_THREADS
2885 res = utime(path, NULL);
2886 Py_END_ALLOW_THREADS
2887 }
2888 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2889 PyErr_SetString(PyExc_TypeError,
2890 "utime() arg 2 must be a tuple (atime, mtime)");
2891 PyMem_Free(path);
2892 return NULL;
2893 }
2894 else {
2895 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2896 &atime, &ausec) == -1) {
2897 PyMem_Free(path);
2898 return NULL;
2899 }
2900 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2901 &mtime, &musec) == -1) {
2902 PyMem_Free(path);
2903 return NULL;
2904 }
2905 ATIME = atime;
2906 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002907#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002908 buf[0].tv_usec = ausec;
2909 buf[1].tv_usec = musec;
2910 Py_BEGIN_ALLOW_THREADS
2911 res = utimes(path, buf);
2912 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002913#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002914 Py_BEGIN_ALLOW_THREADS
2915 res = utime(path, UTIME_ARG);
2916 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002917#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002918 }
2919 if (res < 0) {
2920 return posix_error_with_allocated_filename(path);
2921 }
2922 PyMem_Free(path);
2923 Py_INCREF(Py_None);
2924 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002925#undef UTIME_ARG
2926#undef ATIME
2927#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002928#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002929}
2930
Guido van Rossum85e3b011991-06-03 12:42:10 +00002931
Guido van Rossum3b066191991-06-04 19:40:25 +00002932/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002933
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002934PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002935"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002937
Barry Warsaw53699e91996-12-10 23:23:01 +00002938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002939posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002940{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002941 int sts;
2942 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2943 return NULL;
2944 _exit(sts);
2945 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002946}
2947
Martin v. Löwis114619e2002-10-07 06:44:21 +00002948#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2949static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002950free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002951{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002952 Py_ssize_t i;
2953 for (i = 0; i < count; i++)
2954 PyMem_Free(array[i]);
2955 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956}
2957#endif
2958
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002959
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002960#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002962"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002963Execute an executable path with arguments, replacing current process.\n\
2964\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002965 path: path of executable file\n\
2966 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002967
Barry Warsaw53699e91996-12-10 23:23:01 +00002968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002969posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002970{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002971 char *path;
2972 PyObject *argv;
2973 char **argvlist;
2974 Py_ssize_t i, argc;
2975 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002976
Victor Stinnerd6f85422010-05-05 23:33:33 +00002977 /* execv has two arguments: (path, argv), where
2978 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002979
Victor Stinnerd6f85422010-05-05 23:33:33 +00002980 if (!PyArg_ParseTuple(args, "etO:execv",
2981 Py_FileSystemDefaultEncoding,
2982 &path, &argv))
2983 return NULL;
2984 if (PyList_Check(argv)) {
2985 argc = PyList_Size(argv);
2986 getitem = PyList_GetItem;
2987 }
2988 else if (PyTuple_Check(argv)) {
2989 argc = PyTuple_Size(argv);
2990 getitem = PyTuple_GetItem;
2991 }
2992 else {
2993 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2994 PyMem_Free(path);
2995 return NULL;
2996 }
2997 if (argc < 1) {
2998 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2999 PyMem_Free(path);
3000 return NULL;
3001 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003002
Victor Stinnerd6f85422010-05-05 23:33:33 +00003003 argvlist = PyMem_NEW(char *, argc+1);
3004 if (argvlist == NULL) {
3005 PyMem_Free(path);
3006 return PyErr_NoMemory();
3007 }
3008 for (i = 0; i < argc; i++) {
3009 if (!PyArg_Parse((*getitem)(argv, i), "et",
3010 Py_FileSystemDefaultEncoding,
3011 &argvlist[i])) {
3012 free_string_array(argvlist, i);
3013 PyErr_SetString(PyExc_TypeError,
3014 "execv() arg 2 must contain only strings");
3015 PyMem_Free(path);
3016 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003017
Victor Stinnerd6f85422010-05-05 23:33:33 +00003018 }
3019 }
3020 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003021
Victor Stinnerd6f85422010-05-05 23:33:33 +00003022 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003023
Victor Stinnerd6f85422010-05-05 23:33:33 +00003024 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003025
Victor Stinnerd6f85422010-05-05 23:33:33 +00003026 free_string_array(argvlist, argc);
3027 PyMem_Free(path);
3028 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003029}
3030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003032PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003033"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003034Execute a path with arguments and environment, replacing current process.\n\
3035\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003036 path: path of executable file\n\
3037 args: tuple or list of arguments\n\
3038 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Barry Warsaw53699e91996-12-10 23:23:01 +00003040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003041posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003042{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003043 char *path;
3044 PyObject *argv, *env;
3045 char **argvlist;
3046 char **envlist;
3047 PyObject *key, *val, *keys=NULL, *vals=NULL;
3048 Py_ssize_t i, pos, argc, envc;
3049 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3050 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003051
Victor Stinnerd6f85422010-05-05 23:33:33 +00003052 /* execve has three arguments: (path, argv, env), where
3053 argv is a list or tuple of strings and env is a dictionary
3054 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003055
Victor Stinnerd6f85422010-05-05 23:33:33 +00003056 if (!PyArg_ParseTuple(args, "etOO:execve",
3057 Py_FileSystemDefaultEncoding,
3058 &path, &argv, &env))
3059 return NULL;
3060 if (PyList_Check(argv)) {
3061 argc = PyList_Size(argv);
3062 getitem = PyList_GetItem;
3063 }
3064 else if (PyTuple_Check(argv)) {
3065 argc = PyTuple_Size(argv);
3066 getitem = PyTuple_GetItem;
3067 }
3068 else {
3069 PyErr_SetString(PyExc_TypeError,
3070 "execve() arg 2 must be a tuple or list");
3071 goto fail_0;
3072 }
3073 if (!PyMapping_Check(env)) {
3074 PyErr_SetString(PyExc_TypeError,
3075 "execve() arg 3 must be a mapping object");
3076 goto fail_0;
3077 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003078
Victor Stinnerd6f85422010-05-05 23:33:33 +00003079 argvlist = PyMem_NEW(char *, argc+1);
3080 if (argvlist == NULL) {
3081 PyErr_NoMemory();
3082 goto fail_0;
3083 }
3084 for (i = 0; i < argc; i++) {
3085 if (!PyArg_Parse((*getitem)(argv, i),
3086 "et;execve() arg 2 must contain only strings",
3087 Py_FileSystemDefaultEncoding,
3088 &argvlist[i]))
3089 {
3090 lastarg = i;
3091 goto fail_1;
3092 }
3093 }
3094 lastarg = argc;
3095 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003096
Victor Stinnerd6f85422010-05-05 23:33:33 +00003097 i = PyMapping_Size(env);
3098 if (i < 0)
3099 goto fail_1;
3100 envlist = PyMem_NEW(char *, i + 1);
3101 if (envlist == NULL) {
3102 PyErr_NoMemory();
3103 goto fail_1;
3104 }
3105 envc = 0;
3106 keys = PyMapping_Keys(env);
3107 vals = PyMapping_Values(env);
3108 if (!keys || !vals)
3109 goto fail_2;
3110 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3111 PyErr_SetString(PyExc_TypeError,
3112 "execve(): env.keys() or env.values() is not a list");
3113 goto fail_2;
3114 }
Tim Peters5aa91602002-01-30 05:46:57 +00003115
Victor Stinnerd6f85422010-05-05 23:33:33 +00003116 for (pos = 0; pos < i; pos++) {
3117 char *p, *k, *v;
3118 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003119
Victor Stinnerd6f85422010-05-05 23:33:33 +00003120 key = PyList_GetItem(keys, pos);
3121 val = PyList_GetItem(vals, pos);
3122 if (!key || !val)
3123 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003124
Victor Stinnerd6f85422010-05-05 23:33:33 +00003125 if (!PyArg_Parse(
3126 key,
3127 "s;execve() arg 3 contains a non-string key",
3128 &k) ||
3129 !PyArg_Parse(
3130 val,
3131 "s;execve() arg 3 contains a non-string value",
3132 &v))
3133 {
3134 goto fail_2;
3135 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003136
3137#if defined(PYOS_OS2)
3138 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3139 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3140#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003141 len = PyString_Size(key) + PyString_Size(val) + 2;
3142 p = PyMem_NEW(char, len);
3143 if (p == NULL) {
3144 PyErr_NoMemory();
3145 goto fail_2;
3146 }
3147 PyOS_snprintf(p, len, "%s=%s", k, v);
3148 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003149#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003150 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003151#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003152 }
3153 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003154
Victor Stinnerd6f85422010-05-05 23:33:33 +00003155 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003156
Victor Stinnerd6f85422010-05-05 23:33:33 +00003157 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003158
Victor Stinnerd6f85422010-05-05 23:33:33 +00003159 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003160
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003161 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003162 while (--envc >= 0)
3163 PyMem_DEL(envlist[envc]);
3164 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003165 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003166 free_string_array(argvlist, lastarg);
3167 Py_XDECREF(vals);
3168 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003169 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003170 PyMem_Free(path);
3171 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003172}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003173#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossuma1065681999-01-25 23:20:23 +00003176#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003178"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003179Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003180\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003181 mode: mode of process creation\n\
3182 path: path of executable file\n\
3183 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003184
3185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003186posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003187{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003188 char *path;
3189 PyObject *argv;
3190 char **argvlist;
3191 int mode, i;
3192 Py_ssize_t argc;
3193 Py_intptr_t spawnval;
3194 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003195
Victor Stinnerd6f85422010-05-05 23:33:33 +00003196 /* spawnv has three arguments: (mode, path, argv), where
3197 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003198
Victor Stinnerd6f85422010-05-05 23:33:33 +00003199 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3200 Py_FileSystemDefaultEncoding,
3201 &path, &argv))
3202 return NULL;
3203 if (PyList_Check(argv)) {
3204 argc = PyList_Size(argv);
3205 getitem = PyList_GetItem;
3206 }
3207 else if (PyTuple_Check(argv)) {
3208 argc = PyTuple_Size(argv);
3209 getitem = PyTuple_GetItem;
3210 }
3211 else {
3212 PyErr_SetString(PyExc_TypeError,
3213 "spawnv() arg 2 must be a tuple or list");
3214 PyMem_Free(path);
3215 return NULL;
3216 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003217
Victor Stinnerd6f85422010-05-05 23:33:33 +00003218 argvlist = PyMem_NEW(char *, argc+1);
3219 if (argvlist == NULL) {
3220 PyMem_Free(path);
3221 return PyErr_NoMemory();
3222 }
3223 for (i = 0; i < argc; i++) {
3224 if (!PyArg_Parse((*getitem)(argv, i), "et",
3225 Py_FileSystemDefaultEncoding,
3226 &argvlist[i])) {
3227 free_string_array(argvlist, i);
3228 PyErr_SetString(
3229 PyExc_TypeError,
3230 "spawnv() arg 2 must contain only strings");
3231 PyMem_Free(path);
3232 return NULL;
3233 }
3234 }
3235 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003236
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003237#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003238 Py_BEGIN_ALLOW_THREADS
3239 spawnval = spawnv(mode, path, argvlist);
3240 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003241#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003242 if (mode == _OLD_P_OVERLAY)
3243 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003244
Victor Stinnerd6f85422010-05-05 23:33:33 +00003245 Py_BEGIN_ALLOW_THREADS
3246 spawnval = _spawnv(mode, path, argvlist);
3247 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003248#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003249
Victor Stinnerd6f85422010-05-05 23:33:33 +00003250 free_string_array(argvlist, argc);
3251 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003252
Victor Stinnerd6f85422010-05-05 23:33:33 +00003253 if (spawnval == -1)
3254 return posix_error();
3255 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003256#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003257 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003258#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003259 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003260#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003261}
3262
3263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003264PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003265"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003266Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003267\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003268 mode: mode of process creation\n\
3269 path: path of executable file\n\
3270 args: tuple or list of arguments\n\
3271 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003272
3273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003274posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003275{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003276 char *path;
3277 PyObject *argv, *env;
3278 char **argvlist;
3279 char **envlist;
3280 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3281 int mode, pos, envc;
3282 Py_ssize_t argc, i;
3283 Py_intptr_t spawnval;
3284 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3285 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003286
Victor Stinnerd6f85422010-05-05 23:33:33 +00003287 /* spawnve has four arguments: (mode, path, argv, env), where
3288 argv is a list or tuple of strings and env is a dictionary
3289 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003290
Victor Stinnerd6f85422010-05-05 23:33:33 +00003291 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3292 Py_FileSystemDefaultEncoding,
3293 &path, &argv, &env))
3294 return NULL;
3295 if (PyList_Check(argv)) {
3296 argc = PyList_Size(argv);
3297 getitem = PyList_GetItem;
3298 }
3299 else if (PyTuple_Check(argv)) {
3300 argc = PyTuple_Size(argv);
3301 getitem = PyTuple_GetItem;
3302 }
3303 else {
3304 PyErr_SetString(PyExc_TypeError,
3305 "spawnve() arg 2 must be a tuple or list");
3306 goto fail_0;
3307 }
3308 if (!PyMapping_Check(env)) {
3309 PyErr_SetString(PyExc_TypeError,
3310 "spawnve() arg 3 must be a mapping object");
3311 goto fail_0;
3312 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003313
Victor Stinnerd6f85422010-05-05 23:33:33 +00003314 argvlist = PyMem_NEW(char *, argc+1);
3315 if (argvlist == NULL) {
3316 PyErr_NoMemory();
3317 goto fail_0;
3318 }
3319 for (i = 0; i < argc; i++) {
3320 if (!PyArg_Parse((*getitem)(argv, i),
3321 "et;spawnve() arg 2 must contain only strings",
3322 Py_FileSystemDefaultEncoding,
3323 &argvlist[i]))
3324 {
3325 lastarg = i;
3326 goto fail_1;
3327 }
3328 }
3329 lastarg = argc;
3330 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003331
Victor Stinnerd6f85422010-05-05 23:33:33 +00003332 i = PyMapping_Size(env);
3333 if (i < 0)
3334 goto fail_1;
3335 envlist = PyMem_NEW(char *, i + 1);
3336 if (envlist == NULL) {
3337 PyErr_NoMemory();
3338 goto fail_1;
3339 }
3340 envc = 0;
3341 keys = PyMapping_Keys(env);
3342 vals = PyMapping_Values(env);
3343 if (!keys || !vals)
3344 goto fail_2;
3345 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3346 PyErr_SetString(PyExc_TypeError,
3347 "spawnve(): env.keys() or env.values() is not a list");
3348 goto fail_2;
3349 }
Tim Peters5aa91602002-01-30 05:46:57 +00003350
Victor Stinnerd6f85422010-05-05 23:33:33 +00003351 for (pos = 0; pos < i; pos++) {
3352 char *p, *k, *v;
3353 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003354
Victor Stinnerd6f85422010-05-05 23:33:33 +00003355 key = PyList_GetItem(keys, pos);
3356 val = PyList_GetItem(vals, pos);
3357 if (!key || !val)
3358 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003359
Victor Stinnerd6f85422010-05-05 23:33:33 +00003360 if (!PyArg_Parse(
3361 key,
3362 "s;spawnve() arg 3 contains a non-string key",
3363 &k) ||
3364 !PyArg_Parse(
3365 val,
3366 "s;spawnve() arg 3 contains a non-string value",
3367 &v))
3368 {
3369 goto fail_2;
3370 }
3371 len = PyString_Size(key) + PyString_Size(val) + 2;
3372 p = PyMem_NEW(char, len);
3373 if (p == NULL) {
3374 PyErr_NoMemory();
3375 goto fail_2;
3376 }
3377 PyOS_snprintf(p, len, "%s=%s", k, v);
3378 envlist[envc++] = p;
3379 }
3380 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003381
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003382#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003383 Py_BEGIN_ALLOW_THREADS
3384 spawnval = spawnve(mode, path, argvlist, envlist);
3385 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003386#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003387 if (mode == _OLD_P_OVERLAY)
3388 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003389
Victor Stinnerd6f85422010-05-05 23:33:33 +00003390 Py_BEGIN_ALLOW_THREADS
3391 spawnval = _spawnve(mode, path, argvlist, envlist);
3392 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003393#endif
Tim Peters25059d32001-12-07 20:35:43 +00003394
Victor Stinnerd6f85422010-05-05 23:33:33 +00003395 if (spawnval == -1)
3396 (void) posix_error();
3397 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003398#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003399 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003400#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003401 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003402#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003403
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003404 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003405 while (--envc >= 0)
3406 PyMem_DEL(envlist[envc]);
3407 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003408 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003409 free_string_array(argvlist, lastarg);
3410 Py_XDECREF(vals);
3411 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003412 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003413 PyMem_Free(path);
3414 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003415}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003416
3417/* OS/2 supports spawnvp & spawnvpe natively */
3418#if defined(PYOS_OS2)
3419PyDoc_STRVAR(posix_spawnvp__doc__,
3420"spawnvp(mode, file, args)\n\n\
3421Execute the program 'file' in a new process, using the environment\n\
3422search path to find the file.\n\
3423\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003424 mode: mode of process creation\n\
3425 file: executable file name\n\
3426 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003427
3428static PyObject *
3429posix_spawnvp(PyObject *self, PyObject *args)
3430{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003431 char *path;
3432 PyObject *argv;
3433 char **argvlist;
3434 int mode, i, argc;
3435 Py_intptr_t spawnval;
3436 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003437
Victor Stinnerd6f85422010-05-05 23:33:33 +00003438 /* spawnvp has three arguments: (mode, path, argv), where
3439 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003440
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3442 Py_FileSystemDefaultEncoding,
3443 &path, &argv))
3444 return NULL;
3445 if (PyList_Check(argv)) {
3446 argc = PyList_Size(argv);
3447 getitem = PyList_GetItem;
3448 }
3449 else if (PyTuple_Check(argv)) {
3450 argc = PyTuple_Size(argv);
3451 getitem = PyTuple_GetItem;
3452 }
3453 else {
3454 PyErr_SetString(PyExc_TypeError,
3455 "spawnvp() arg 2 must be a tuple or list");
3456 PyMem_Free(path);
3457 return NULL;
3458 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003459
Victor Stinnerd6f85422010-05-05 23:33:33 +00003460 argvlist = PyMem_NEW(char *, argc+1);
3461 if (argvlist == NULL) {
3462 PyMem_Free(path);
3463 return PyErr_NoMemory();
3464 }
3465 for (i = 0; i < argc; i++) {
3466 if (!PyArg_Parse((*getitem)(argv, i), "et",
3467 Py_FileSystemDefaultEncoding,
3468 &argvlist[i])) {
3469 free_string_array(argvlist, i);
3470 PyErr_SetString(
3471 PyExc_TypeError,
3472 "spawnvp() arg 2 must contain only strings");
3473 PyMem_Free(path);
3474 return NULL;
3475 }
3476 }
3477 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003478
Victor Stinnerd6f85422010-05-05 23:33:33 +00003479 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003480#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003481 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003482#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003484#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003485 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003486
Victor Stinnerd6f85422010-05-05 23:33:33 +00003487 free_string_array(argvlist, argc);
3488 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003489
Victor Stinnerd6f85422010-05-05 23:33:33 +00003490 if (spawnval == -1)
3491 return posix_error();
3492 else
3493 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003494}
3495
3496
3497PyDoc_STRVAR(posix_spawnvpe__doc__,
3498"spawnvpe(mode, file, args, env)\n\n\
3499Execute the program 'file' in a new process, using the environment\n\
3500search path to find the file.\n\
3501\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003502 mode: mode of process creation\n\
3503 file: executable file name\n\
3504 args: tuple or list of arguments\n\
3505 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003506
3507static PyObject *
3508posix_spawnvpe(PyObject *self, PyObject *args)
3509{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003510 char *path;
3511 PyObject *argv, *env;
3512 char **argvlist;
3513 char **envlist;
3514 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3515 int mode, i, pos, argc, envc;
3516 Py_intptr_t spawnval;
3517 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3518 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003519
Victor Stinnerd6f85422010-05-05 23:33:33 +00003520 /* spawnvpe has four arguments: (mode, path, argv, env), where
3521 argv is a list or tuple of strings and env is a dictionary
3522 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003523
Victor Stinnerd6f85422010-05-05 23:33:33 +00003524 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3525 Py_FileSystemDefaultEncoding,
3526 &path, &argv, &env))
3527 return NULL;
3528 if (PyList_Check(argv)) {
3529 argc = PyList_Size(argv);
3530 getitem = PyList_GetItem;
3531 }
3532 else if (PyTuple_Check(argv)) {
3533 argc = PyTuple_Size(argv);
3534 getitem = PyTuple_GetItem;
3535 }
3536 else {
3537 PyErr_SetString(PyExc_TypeError,
3538 "spawnvpe() arg 2 must be a tuple or list");
3539 goto fail_0;
3540 }
3541 if (!PyMapping_Check(env)) {
3542 PyErr_SetString(PyExc_TypeError,
3543 "spawnvpe() arg 3 must be a mapping object");
3544 goto fail_0;
3545 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003546
Victor Stinnerd6f85422010-05-05 23:33:33 +00003547 argvlist = PyMem_NEW(char *, argc+1);
3548 if (argvlist == NULL) {
3549 PyErr_NoMemory();
3550 goto fail_0;
3551 }
3552 for (i = 0; i < argc; i++) {
3553 if (!PyArg_Parse((*getitem)(argv, i),
3554 "et;spawnvpe() arg 2 must contain only strings",
3555 Py_FileSystemDefaultEncoding,
3556 &argvlist[i]))
3557 {
3558 lastarg = i;
3559 goto fail_1;
3560 }
3561 }
3562 lastarg = argc;
3563 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003564
Victor Stinnerd6f85422010-05-05 23:33:33 +00003565 i = PyMapping_Size(env);
3566 if (i < 0)
3567 goto fail_1;
3568 envlist = PyMem_NEW(char *, i + 1);
3569 if (envlist == NULL) {
3570 PyErr_NoMemory();
3571 goto fail_1;
3572 }
3573 envc = 0;
3574 keys = PyMapping_Keys(env);
3575 vals = PyMapping_Values(env);
3576 if (!keys || !vals)
3577 goto fail_2;
3578 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3579 PyErr_SetString(PyExc_TypeError,
3580 "spawnvpe(): env.keys() or env.values() is not a list");
3581 goto fail_2;
3582 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003583
Victor Stinnerd6f85422010-05-05 23:33:33 +00003584 for (pos = 0; pos < i; pos++) {
3585 char *p, *k, *v;
3586 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003587
Victor Stinnerd6f85422010-05-05 23:33:33 +00003588 key = PyList_GetItem(keys, pos);
3589 val = PyList_GetItem(vals, pos);
3590 if (!key || !val)
3591 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003592
Victor Stinnerd6f85422010-05-05 23:33:33 +00003593 if (!PyArg_Parse(
3594 key,
3595 "s;spawnvpe() arg 3 contains a non-string key",
3596 &k) ||
3597 !PyArg_Parse(
3598 val,
3599 "s;spawnvpe() arg 3 contains a non-string value",
3600 &v))
3601 {
3602 goto fail_2;
3603 }
3604 len = PyString_Size(key) + PyString_Size(val) + 2;
3605 p = PyMem_NEW(char, len);
3606 if (p == NULL) {
3607 PyErr_NoMemory();
3608 goto fail_2;
3609 }
3610 PyOS_snprintf(p, len, "%s=%s", k, v);
3611 envlist[envc++] = p;
3612 }
3613 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003614
Victor Stinnerd6f85422010-05-05 23:33:33 +00003615 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003616#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003617 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003618#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003619 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003621 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003622
Victor Stinnerd6f85422010-05-05 23:33:33 +00003623 if (spawnval == -1)
3624 (void) posix_error();
3625 else
3626 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003627
3628 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003629 while (--envc >= 0)
3630 PyMem_DEL(envlist[envc]);
3631 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003632 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003633 free_string_array(argvlist, lastarg);
3634 Py_XDECREF(vals);
3635 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003636 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003637 PyMem_Free(path);
3638 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003639}
3640#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003641#endif /* HAVE_SPAWNV */
3642
3643
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003644#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003645PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003646"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003647Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3648\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003649Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003650
3651static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003652posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003653{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003654 pid_t pid;
3655 int result = 0;
3656 _PyImport_AcquireLock();
3657 pid = fork1();
3658 if (pid == 0) {
3659 /* child: this clobbers and resets the import lock. */
3660 PyOS_AfterFork();
3661 } else {
3662 /* parent: release the import lock. */
3663 result = _PyImport_ReleaseLock();
3664 }
3665 if (pid == -1)
3666 return posix_error();
3667 if (result < 0) {
3668 /* Don't clobber the OSError if the fork failed. */
3669 PyErr_SetString(PyExc_RuntimeError,
3670 "not holding the import lock");
3671 return NULL;
3672 }
3673 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003674}
3675#endif
3676
3677
Guido van Rossumad0ee831995-03-01 10:34:45 +00003678#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003679PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003680"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003681Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003682Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683
Barry Warsaw53699e91996-12-10 23:23:01 +00003684static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003685posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003686{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003687 pid_t pid;
3688 int result = 0;
3689 _PyImport_AcquireLock();
3690 pid = fork();
3691 if (pid == 0) {
3692 /* child: this clobbers and resets the import lock. */
3693 PyOS_AfterFork();
3694 } else {
3695 /* parent: release the import lock. */
3696 result = _PyImport_ReleaseLock();
3697 }
3698 if (pid == -1)
3699 return posix_error();
3700 if (result < 0) {
3701 /* Don't clobber the OSError if the fork failed. */
3702 PyErr_SetString(PyExc_RuntimeError,
3703 "not holding the import lock");
3704 return NULL;
3705 }
3706 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003707}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003708#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003709
Neal Norwitzb59798b2003-03-21 01:43:31 +00003710/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003711/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3712#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003713#define DEV_PTY_FILE "/dev/ptc"
3714#define HAVE_DEV_PTMX
3715#else
3716#define DEV_PTY_FILE "/dev/ptmx"
3717#endif
3718
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003719#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003720#ifdef HAVE_PTY_H
3721#include <pty.h>
3722#else
3723#ifdef HAVE_LIBUTIL_H
3724#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003725#else
3726#ifdef HAVE_UTIL_H
3727#include <util.h>
3728#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003729#endif /* HAVE_LIBUTIL_H */
3730#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003731#ifdef HAVE_STROPTS_H
3732#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003733#endif
3734#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003735
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003736#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003737PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003738"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003739Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003740
3741static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003742posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003743{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003744 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003745#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003746 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003747#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003748#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003749 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003750#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003751 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003752#endif
3753#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003754
Thomas Wouters70c21a12000-07-14 14:28:33 +00003755#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003756 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3757 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003758#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003759 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3760 if (slave_name == NULL)
3761 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003762
Victor Stinnerd6f85422010-05-05 23:33:33 +00003763 slave_fd = open(slave_name, O_RDWR);
3764 if (slave_fd < 0)
3765 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003766#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003767 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3768 if (master_fd < 0)
3769 return posix_error();
3770 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3771 /* change permission of slave */
3772 if (grantpt(master_fd) < 0) {
3773 PyOS_setsig(SIGCHLD, sig_saved);
3774 return posix_error();
3775 }
3776 /* unlock slave */
3777 if (unlockpt(master_fd) < 0) {
3778 PyOS_setsig(SIGCHLD, sig_saved);
3779 return posix_error();
3780 }
3781 PyOS_setsig(SIGCHLD, sig_saved);
3782 slave_name = ptsname(master_fd); /* get name of slave */
3783 if (slave_name == NULL)
3784 return posix_error();
3785 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3786 if (slave_fd < 0)
3787 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003788#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003789 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3790 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003791#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003792 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003793#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003794#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003795#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003796
Victor Stinnerd6f85422010-05-05 23:33:33 +00003797 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003798
Fred Drake8cef4cf2000-06-28 16:40:38 +00003799}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003800#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003801
3802#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003803PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003804"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003805Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3806Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003807To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003808
3809static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003810posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003811{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003812 int master_fd = -1, result = 0;
3813 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003814
Victor Stinnerd6f85422010-05-05 23:33:33 +00003815 _PyImport_AcquireLock();
3816 pid = forkpty(&master_fd, NULL, NULL, NULL);
3817 if (pid == 0) {
3818 /* child: this clobbers and resets the import lock. */
3819 PyOS_AfterFork();
3820 } else {
3821 /* parent: release the import lock. */
3822 result = _PyImport_ReleaseLock();
3823 }
3824 if (pid == -1)
3825 return posix_error();
3826 if (result < 0) {
3827 /* Don't clobber the OSError if the fork failed. */
3828 PyErr_SetString(PyExc_RuntimeError,
3829 "not holding the import lock");
3830 return NULL;
3831 }
3832 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003833}
3834#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835
Guido van Rossumad0ee831995-03-01 10:34:45 +00003836#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003837PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003838"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Barry Warsaw53699e91996-12-10 23:23:01 +00003841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003842posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003844 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003845}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003846#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003848
Guido van Rossumad0ee831995-03-01 10:34:45 +00003849#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003850PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003851"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003852Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003853
Barry Warsaw53699e91996-12-10 23:23:01 +00003854static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003855posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003856{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003857 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003858}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003859#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003861
Guido van Rossumad0ee831995-03-01 10:34:45 +00003862#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003863PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003864"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003865Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003866
Barry Warsaw53699e91996-12-10 23:23:01 +00003867static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003868posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003870 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003871}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003872#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003873
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003874
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003875PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003876"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003878
Barry Warsaw53699e91996-12-10 23:23:01 +00003879static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003880posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003881{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003882 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003883}
3884
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003885
Fred Drakec9680921999-12-13 16:37:25 +00003886#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003887PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003888"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003890
3891static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003892posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003893{
3894 PyObject *result = NULL;
3895
Fred Drakec9680921999-12-13 16:37:25 +00003896#ifdef NGROUPS_MAX
3897#define MAX_GROUPS NGROUPS_MAX
3898#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003899 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003900#define MAX_GROUPS 64
3901#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003902 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003903
3904 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
3905 * This is a helper variable to store the intermediate result when
3906 * that happens.
3907 *
3908 * To keep the code readable the OSX behaviour is unconditional,
3909 * according to the POSIX spec this should be safe on all unix-y
3910 * systems.
3911 */
3912 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003913 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003914
Victor Stinnerd6f85422010-05-05 23:33:33 +00003915 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003916 if (n < 0) {
3917 if (errno == EINVAL) {
3918 n = getgroups(0, NULL);
3919 if (n == -1) {
3920 return posix_error();
3921 }
3922 if (n == 0) {
3923 /* Avoid malloc(0) */
3924 alt_grouplist = grouplist;
3925 } else {
3926 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
3927 if (alt_grouplist == NULL) {
3928 errno = EINVAL;
3929 return posix_error();
3930 }
3931 n = getgroups(n, alt_grouplist);
3932 if (n == -1) {
3933 PyMem_Free(alt_grouplist);
3934 return posix_error();
3935 }
3936 }
3937 } else {
3938 return posix_error();
3939 }
3940 }
3941 result = PyList_New(n);
3942 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00003943 int i;
3944 for (i = 0; i < n; ++i) {
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003945 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003946 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00003947 Py_DECREF(result);
3948 result = NULL;
3949 break;
Fred Drakec9680921999-12-13 16:37:25 +00003950 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003951 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003952 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003953 }
3954
3955 if (alt_grouplist != grouplist) {
3956 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003957 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003958
Fred Drakec9680921999-12-13 16:37:25 +00003959 return result;
3960}
3961#endif
3962
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003963#ifdef HAVE_INITGROUPS
3964PyDoc_STRVAR(posix_initgroups__doc__,
3965"initgroups(username, gid) -> None\n\n\
3966Call the system initgroups() to initialize the group access list with all of\n\
3967the groups of which the specified username is a member, plus the specified\n\
3968group id.");
3969
3970static PyObject *
3971posix_initgroups(PyObject *self, PyObject *args)
3972{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003973 char *username;
3974 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003975
Victor Stinnerd6f85422010-05-05 23:33:33 +00003976 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3977 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003978
Victor Stinnerd6f85422010-05-05 23:33:33 +00003979 if (initgroups(username, (gid_t) gid) == -1)
3980 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003981
Victor Stinnerd6f85422010-05-05 23:33:33 +00003982 Py_INCREF(Py_None);
3983 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003984}
3985#endif
3986
Martin v. Löwis606edc12002-06-13 21:09:11 +00003987#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003988PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003990Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003991
3992static PyObject *
3993posix_getpgid(PyObject *self, PyObject *args)
3994{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003995 pid_t pid, pgid;
3996 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3997 return NULL;
3998 pgid = getpgid(pid);
3999 if (pgid < 0)
4000 return posix_error();
4001 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004002}
4003#endif /* HAVE_GETPGID */
4004
4005
Guido van Rossumb6775db1994-08-01 11:34:53 +00004006#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004008"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004010
Barry Warsaw53699e91996-12-10 23:23:01 +00004011static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004012posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004013{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004014#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004015 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004016#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004017 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004018#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004019}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004020#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004022
Guido van Rossumb6775db1994-08-01 11:34:53 +00004023#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004024PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004025"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004026Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004027
Barry Warsaw53699e91996-12-10 23:23:01 +00004028static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004029posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004030{
Guido van Rossum64933891994-10-20 21:56:42 +00004031#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004032 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004033#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004034 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004035#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004036 return posix_error();
4037 Py_INCREF(Py_None);
4038 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004039}
4040
Guido van Rossumb6775db1994-08-01 11:34:53 +00004041#endif /* HAVE_SETPGRP */
4042
Guido van Rossumad0ee831995-03-01 10:34:45 +00004043#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004044PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004045"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004046Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004047
Barry Warsaw53699e91996-12-10 23:23:01 +00004048static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004049posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004050{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004051 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004052}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004053#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Fred Drake12c6e2d1999-12-14 21:25:03 +00004056#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004057PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004058"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004060
4061static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004062posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004063{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004064 PyObject *result = NULL;
4065 char *name;
4066 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004067
Victor Stinnerd6f85422010-05-05 23:33:33 +00004068 errno = 0;
4069 name = getlogin();
4070 if (name == NULL) {
4071 if (errno)
4072 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004073 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004074 PyErr_SetString(PyExc_OSError,
4075 "unable to determine login name");
4076 }
4077 else
4078 result = PyString_FromString(name);
4079 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004080
Fred Drake12c6e2d1999-12-14 21:25:03 +00004081 return result;
4082}
4083#endif
4084
Guido van Rossumad0ee831995-03-01 10:34:45 +00004085#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004087"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004088Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004091posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004092{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004093 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004094}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004095#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004097
Guido van Rossumad0ee831995-03-01 10:34:45 +00004098#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004099PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004100"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004101Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004104posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004105{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004106 pid_t pid;
4107 int sig;
4108 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4109 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004110#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004111 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4112 APIRET rc;
4113 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004114 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004115
4116 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4117 APIRET rc;
4118 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004119 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004120
4121 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004122 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004123#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004124 if (kill(pid, sig) == -1)
4125 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004126#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004127 Py_INCREF(Py_None);
4128 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004129}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004130#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004131
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004132#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004133PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004134"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004135Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004136
4137static PyObject *
4138posix_killpg(PyObject *self, PyObject *args)
4139{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004140 int sig;
4141 pid_t pgid;
4142 /* XXX some man pages make the `pgid` parameter an int, others
4143 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4144 take the same type. Moreover, pid_t is always at least as wide as
4145 int (else compilation of this module fails), which is safe. */
4146 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4147 return NULL;
4148 if (killpg(pgid, sig) == -1)
4149 return posix_error();
4150 Py_INCREF(Py_None);
4151 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004152}
4153#endif
4154
Brian Curtine5aa8862010-04-02 23:26:06 +00004155#ifdef MS_WINDOWS
4156PyDoc_STRVAR(win32_kill__doc__,
4157"kill(pid, sig)\n\n\
4158Kill a process with a signal.");
4159
4160static PyObject *
4161win32_kill(PyObject *self, PyObject *args)
4162{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004163 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004164 DWORD pid, sig, err;
4165 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004166
Victor Stinnerd6f85422010-05-05 23:33:33 +00004167 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4168 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004169
Victor Stinnerd6f85422010-05-05 23:33:33 +00004170 /* Console processes which share a common console can be sent CTRL+C or
4171 CTRL+BREAK events, provided they handle said events. */
4172 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4173 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4174 err = GetLastError();
4175 return PyErr_SetFromWindowsErr(err);
4176 }
4177 else
4178 Py_RETURN_NONE;
4179 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004180
Victor Stinnerd6f85422010-05-05 23:33:33 +00004181 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4182 attempt to open and terminate the process. */
4183 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4184 if (handle == NULL) {
4185 err = GetLastError();
4186 return PyErr_SetFromWindowsErr(err);
4187 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004188
Victor Stinnerd6f85422010-05-05 23:33:33 +00004189 if (TerminateProcess(handle, sig) == 0) {
4190 err = GetLastError();
4191 result = PyErr_SetFromWindowsErr(err);
4192 } else {
4193 Py_INCREF(Py_None);
4194 result = Py_None;
4195 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004196
Victor Stinnerd6f85422010-05-05 23:33:33 +00004197 CloseHandle(handle);
4198 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004199}
4200#endif /* MS_WINDOWS */
4201
Guido van Rossumc0125471996-06-28 18:55:32 +00004202#ifdef HAVE_PLOCK
4203
4204#ifdef HAVE_SYS_LOCK_H
4205#include <sys/lock.h>
4206#endif
4207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004208PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004209"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004210Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004211
Barry Warsaw53699e91996-12-10 23:23:01 +00004212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004213posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004214{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004215 int op;
4216 if (!PyArg_ParseTuple(args, "i:plock", &op))
4217 return NULL;
4218 if (plock(op) == -1)
4219 return posix_error();
4220 Py_INCREF(Py_None);
4221 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004222}
4223#endif
4224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004225
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004226#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004227PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004228"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004229Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004230
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004231#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004232#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004233static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004234async_system(const char *command)
4235{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004236 char errormsg[256], args[1024];
4237 RESULTCODES rcodes;
4238 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004239
Victor Stinnerd6f85422010-05-05 23:33:33 +00004240 char *shell = getenv("COMSPEC");
4241 if (!shell)
4242 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004243
Victor Stinnerd6f85422010-05-05 23:33:33 +00004244 /* avoid overflowing the argument buffer */
4245 if (strlen(shell) + 3 + strlen(command) >= 1024)
4246 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004247
Victor Stinnerd6f85422010-05-05 23:33:33 +00004248 args[0] = '\0';
4249 strcat(args, shell);
4250 strcat(args, "/c ");
4251 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004252
Victor Stinnerd6f85422010-05-05 23:33:33 +00004253 /* execute asynchronously, inheriting the environment */
4254 rc = DosExecPgm(errormsg,
4255 sizeof(errormsg),
4256 EXEC_ASYNC,
4257 args,
4258 NULL,
4259 &rcodes,
4260 shell);
4261 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004262}
4263
Guido van Rossumd48f2521997-12-05 22:19:34 +00004264static FILE *
4265popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004266{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004267 int oldfd, tgtfd;
4268 HFILE pipeh[2];
4269 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004270
Victor Stinnerd6f85422010-05-05 23:33:33 +00004271 /* mode determines which of stdin or stdout is reconnected to
4272 * the pipe to the child
4273 */
4274 if (strchr(mode, 'r') != NULL) {
4275 tgt_fd = 1; /* stdout */
4276 } else if (strchr(mode, 'w')) {
4277 tgt_fd = 0; /* stdin */
4278 } else {
4279 *err = ERROR_INVALID_ACCESS;
4280 return NULL;
4281 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004282
Victor Stinnerd6f85422010-05-05 23:33:33 +00004283 /* setup the pipe */
4284 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4285 *err = rc;
4286 return NULL;
4287 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004288
Victor Stinnerd6f85422010-05-05 23:33:33 +00004289 /* prevent other threads accessing stdio */
4290 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004291
Victor Stinnerd6f85422010-05-05 23:33:33 +00004292 /* reconnect stdio and execute child */
4293 oldfd = dup(tgtfd);
4294 close(tgtfd);
4295 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4296 DosClose(pipeh[tgtfd]);
4297 rc = async_system(command);
4298 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004299
Victor Stinnerd6f85422010-05-05 23:33:33 +00004300 /* restore stdio */
4301 dup2(oldfd, tgtfd);
4302 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004303
Victor Stinnerd6f85422010-05-05 23:33:33 +00004304 /* allow other threads access to stdio */
4305 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004306
Victor Stinnerd6f85422010-05-05 23:33:33 +00004307 /* if execution of child was successful return file stream */
4308 if (rc == NO_ERROR)
4309 return fdopen(pipeh[1 - tgtfd], mode);
4310 else {
4311 DosClose(pipeh[1 - tgtfd]);
4312 *err = rc;
4313 return NULL;
4314 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004315}
4316
4317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004318posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004319{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004320 char *name;
4321 char *mode = "r";
4322 int err, bufsize = -1;
4323 FILE *fp;
4324 PyObject *f;
4325 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4326 return NULL;
4327 Py_BEGIN_ALLOW_THREADS
4328 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4329 Py_END_ALLOW_THREADS
4330 if (fp == NULL)
4331 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004332
Victor Stinnerd6f85422010-05-05 23:33:33 +00004333 f = PyFile_FromFile(fp, name, mode, fclose);
4334 if (f != NULL)
4335 PyFile_SetBufSize(f, bufsize);
4336 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004337}
4338
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004339#elif defined(PYCC_GCC)
4340
4341/* standard posix version of popen() support */
4342static PyObject *
4343posix_popen(PyObject *self, PyObject *args)
4344{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004345 char *name;
4346 char *mode = "r";
4347 int bufsize = -1;
4348 FILE *fp;
4349 PyObject *f;
4350 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4351 return NULL;
4352 Py_BEGIN_ALLOW_THREADS
4353 fp = popen(name, mode);
4354 Py_END_ALLOW_THREADS
4355 if (fp == NULL)
4356 return posix_error();
4357 f = PyFile_FromFile(fp, name, mode, pclose);
4358 if (f != NULL)
4359 PyFile_SetBufSize(f, bufsize);
4360 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004361}
4362
4363/* fork() under OS/2 has lots'o'warts
4364 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4365 * most of this code is a ripoff of the win32 code, but using the
4366 * capabilities of EMX's C library routines
4367 */
4368
4369/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4370#define POPEN_1 1
4371#define POPEN_2 2
4372#define POPEN_3 3
4373#define POPEN_4 4
4374
4375static PyObject *_PyPopen(char *, int, int, int);
4376static int _PyPclose(FILE *file);
4377
4378/*
4379 * Internal dictionary mapping popen* file pointers to process handles,
4380 * for use when retrieving the process exit code. See _PyPclose() below
4381 * for more information on this dictionary's use.
4382 */
4383static PyObject *_PyPopenProcs = NULL;
4384
4385/* os2emx version of popen2()
4386 *
4387 * The result of this function is a pipe (file) connected to the
4388 * process's stdin, and a pipe connected to the process's stdout.
4389 */
4390
4391static PyObject *
4392os2emx_popen2(PyObject *self, PyObject *args)
4393{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004394 PyObject *f;
4395 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004396
Victor Stinnerd6f85422010-05-05 23:33:33 +00004397 char *cmdstring;
4398 char *mode = "t";
4399 int bufsize = -1;
4400 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4401 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004402
Victor Stinnerd6f85422010-05-05 23:33:33 +00004403 if (*mode == 't')
4404 tm = O_TEXT;
4405 else if (*mode != 'b') {
4406 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4407 return NULL;
4408 } else
4409 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004410
Victor Stinnerd6f85422010-05-05 23:33:33 +00004411 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004412
Victor Stinnerd6f85422010-05-05 23:33:33 +00004413 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004414}
4415
4416/*
4417 * Variation on os2emx.popen2
4418 *
4419 * The result of this function is 3 pipes - the process's stdin,
4420 * stdout and stderr
4421 */
4422
4423static PyObject *
4424os2emx_popen3(PyObject *self, PyObject *args)
4425{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004426 PyObject *f;
4427 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004428
Victor Stinnerd6f85422010-05-05 23:33:33 +00004429 char *cmdstring;
4430 char *mode = "t";
4431 int bufsize = -1;
4432 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4433 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004434
Victor Stinnerd6f85422010-05-05 23:33:33 +00004435 if (*mode == 't')
4436 tm = O_TEXT;
4437 else if (*mode != 'b') {
4438 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4439 return NULL;
4440 } else
4441 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004442
Victor Stinnerd6f85422010-05-05 23:33:33 +00004443 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004444
Victor Stinnerd6f85422010-05-05 23:33:33 +00004445 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004446}
4447
4448/*
4449 * Variation on os2emx.popen2
4450 *
Tim Peters11b23062003-04-23 02:39:17 +00004451 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004452 * and stdout+stderr combined as a single pipe.
4453 */
4454
4455static PyObject *
4456os2emx_popen4(PyObject *self, PyObject *args)
4457{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004458 PyObject *f;
4459 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004460
Victor Stinnerd6f85422010-05-05 23:33:33 +00004461 char *cmdstring;
4462 char *mode = "t";
4463 int bufsize = -1;
4464 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4465 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004466
Victor Stinnerd6f85422010-05-05 23:33:33 +00004467 if (*mode == 't')
4468 tm = O_TEXT;
4469 else if (*mode != 'b') {
4470 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4471 return NULL;
4472 } else
4473 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004474
Victor Stinnerd6f85422010-05-05 23:33:33 +00004475 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004476
Victor Stinnerd6f85422010-05-05 23:33:33 +00004477 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004478}
4479
4480/* a couple of structures for convenient handling of multiple
4481 * file handles and pipes
4482 */
4483struct file_ref
4484{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004485 int handle;
4486 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004487};
4488
4489struct pipe_ref
4490{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004491 int rd;
4492 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004493};
4494
4495/* The following code is derived from the win32 code */
4496
4497static PyObject *
4498_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4499{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004500 struct file_ref stdio[3];
4501 struct pipe_ref p_fd[3];
4502 FILE *p_s[3];
4503 int file_count, i, pipe_err;
4504 pid_t pipe_pid;
4505 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4506 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004507
Victor Stinnerd6f85422010-05-05 23:33:33 +00004508 /* file modes for subsequent fdopen's on pipe handles */
4509 if (mode == O_TEXT)
4510 {
4511 rd_mode = "rt";
4512 wr_mode = "wt";
4513 }
4514 else
4515 {
4516 rd_mode = "rb";
4517 wr_mode = "wb";
4518 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004519
Victor Stinnerd6f85422010-05-05 23:33:33 +00004520 /* prepare shell references */
4521 if ((shell = getenv("EMXSHELL")) == NULL)
4522 if ((shell = getenv("COMSPEC")) == NULL)
4523 {
4524 errno = ENOENT;
4525 return posix_error();
4526 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004527
Victor Stinnerd6f85422010-05-05 23:33:33 +00004528 sh_name = _getname(shell);
4529 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4530 opt = "/c";
4531 else
4532 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004533
Victor Stinnerd6f85422010-05-05 23:33:33 +00004534 /* save current stdio fds + their flags, and set not inheritable */
4535 i = pipe_err = 0;
4536 while (pipe_err >= 0 && i < 3)
4537 {
4538 pipe_err = stdio[i].handle = dup(i);
4539 stdio[i].flags = fcntl(i, F_GETFD, 0);
4540 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4541 i++;
4542 }
4543 if (pipe_err < 0)
4544 {
4545 /* didn't get them all saved - clean up and bail out */
4546 int saved_err = errno;
4547 while (i-- > 0)
4548 {
4549 close(stdio[i].handle);
4550 }
4551 errno = saved_err;
4552 return posix_error();
4553 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004554
Victor Stinnerd6f85422010-05-05 23:33:33 +00004555 /* create pipe ends */
4556 file_count = 2;
4557 if (n == POPEN_3)
4558 file_count = 3;
4559 i = pipe_err = 0;
4560 while ((pipe_err == 0) && (i < file_count))
4561 pipe_err = pipe((int *)&p_fd[i++]);
4562 if (pipe_err < 0)
4563 {
4564 /* didn't get them all made - clean up and bail out */
4565 while (i-- > 0)
4566 {
4567 close(p_fd[i].wr);
4568 close(p_fd[i].rd);
4569 }
4570 errno = EPIPE;
4571 return posix_error();
4572 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004573
Victor Stinnerd6f85422010-05-05 23:33:33 +00004574 /* change the actual standard IO streams over temporarily,
4575 * making the retained pipe ends non-inheritable
4576 */
4577 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004578
Victor Stinnerd6f85422010-05-05 23:33:33 +00004579 /* - stdin */
4580 if (dup2(p_fd[0].rd, 0) == 0)
4581 {
4582 close(p_fd[0].rd);
4583 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4584 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4585 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4586 {
4587 close(p_fd[0].wr);
4588 pipe_err = -1;
4589 }
4590 }
4591 else
4592 {
4593 pipe_err = -1;
4594 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004595
Victor Stinnerd6f85422010-05-05 23:33:33 +00004596 /* - stdout */
4597 if (pipe_err == 0)
4598 {
4599 if (dup2(p_fd[1].wr, 1) == 1)
4600 {
4601 close(p_fd[1].wr);
4602 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4603 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4604 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4605 {
4606 close(p_fd[1].rd);
4607 pipe_err = -1;
4608 }
4609 }
4610 else
4611 {
4612 pipe_err = -1;
4613 }
4614 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615
Victor Stinnerd6f85422010-05-05 23:33:33 +00004616 /* - stderr, as required */
4617 if (pipe_err == 0)
4618 switch (n)
4619 {
4620 case POPEN_3:
4621 {
4622 if (dup2(p_fd[2].wr, 2) == 2)
4623 {
4624 close(p_fd[2].wr);
4625 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4626 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4627 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4628 {
4629 close(p_fd[2].rd);
4630 pipe_err = -1;
4631 }
4632 }
4633 else
4634 {
4635 pipe_err = -1;
4636 }
4637 break;
4638 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004639
Victor Stinnerd6f85422010-05-05 23:33:33 +00004640 case POPEN_4:
4641 {
4642 if (dup2(1, 2) != 2)
4643 {
4644 pipe_err = -1;
4645 }
4646 break;
4647 }
4648 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004649
Victor Stinnerd6f85422010-05-05 23:33:33 +00004650 /* spawn the child process */
4651 if (pipe_err == 0)
4652 {
4653 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4654 if (pipe_pid == -1)
4655 {
4656 pipe_err = -1;
4657 }
4658 else
4659 {
4660 /* save the PID into the FILE structure
4661 * NOTE: this implementation doesn't actually
4662 * take advantage of this, but do it for
4663 * completeness - AIM Apr01
4664 */
4665 for (i = 0; i < file_count; i++)
4666 p_s[i]->_pid = pipe_pid;
4667 }
4668 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004669
Victor Stinnerd6f85422010-05-05 23:33:33 +00004670 /* reset standard IO to normal */
4671 for (i = 0; i < 3; i++)
4672 {
4673 dup2(stdio[i].handle, i);
4674 fcntl(i, F_SETFD, stdio[i].flags);
4675 close(stdio[i].handle);
4676 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004677
Victor Stinnerd6f85422010-05-05 23:33:33 +00004678 /* if any remnant problems, clean up and bail out */
4679 if (pipe_err < 0)
4680 {
4681 for (i = 0; i < 3; i++)
4682 {
4683 close(p_fd[i].rd);
4684 close(p_fd[i].wr);
4685 }
4686 errno = EPIPE;
4687 return posix_error_with_filename(cmdstring);
4688 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004689
Victor Stinnerd6f85422010-05-05 23:33:33 +00004690 /* build tuple of file objects to return */
4691 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4692 PyFile_SetBufSize(p_f[0], bufsize);
4693 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4694 PyFile_SetBufSize(p_f[1], bufsize);
4695 if (n == POPEN_3)
4696 {
4697 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4698 PyFile_SetBufSize(p_f[0], bufsize);
4699 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4700 }
4701 else
4702 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004703
Victor Stinnerd6f85422010-05-05 23:33:33 +00004704 /*
4705 * Insert the files we've created into the process dictionary
4706 * all referencing the list with the process handle and the
4707 * initial number of files (see description below in _PyPclose).
4708 * Since if _PyPclose later tried to wait on a process when all
4709 * handles weren't closed, it could create a deadlock with the
4710 * child, we spend some energy here to try to ensure that we
4711 * either insert all file handles into the dictionary or none
4712 * at all. It's a little clumsy with the various popen modes
4713 * and variable number of files involved.
4714 */
4715 if (!_PyPopenProcs)
4716 {
4717 _PyPopenProcs = PyDict_New();
4718 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004719
Victor Stinnerd6f85422010-05-05 23:33:33 +00004720 if (_PyPopenProcs)
4721 {
4722 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4723 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004724
Victor Stinnerd6f85422010-05-05 23:33:33 +00004725 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4726 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004727
Victor Stinnerd6f85422010-05-05 23:33:33 +00004728 procObj = PyList_New(2);
4729 pidObj = PyLong_FromPid(pipe_pid);
4730 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004731
Victor Stinnerd6f85422010-05-05 23:33:33 +00004732 if (procObj && pidObj && intObj)
4733 {
4734 PyList_SetItem(procObj, 0, pidObj);
4735 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004736
Victor Stinnerd6f85422010-05-05 23:33:33 +00004737 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4738 if (fileObj[0])
4739 {
4740 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4741 fileObj[0],
4742 procObj);
4743 }
4744 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4745 if (fileObj[1])
4746 {
4747 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4748 fileObj[1],
4749 procObj);
4750 }
4751 if (file_count >= 3)
4752 {
4753 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4754 if (fileObj[2])
4755 {
4756 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4757 fileObj[2],
4758 procObj);
4759 }
4760 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004761
Victor Stinnerd6f85422010-05-05 23:33:33 +00004762 if (ins_rc[0] < 0 || !fileObj[0] ||
4763 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4764 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4765 {
4766 /* Something failed - remove any dictionary
4767 * entries that did make it.
4768 */
4769 if (!ins_rc[0] && fileObj[0])
4770 {
4771 PyDict_DelItem(_PyPopenProcs,
4772 fileObj[0]);
4773 }
4774 if (!ins_rc[1] && fileObj[1])
4775 {
4776 PyDict_DelItem(_PyPopenProcs,
4777 fileObj[1]);
4778 }
4779 if (!ins_rc[2] && fileObj[2])
4780 {
4781 PyDict_DelItem(_PyPopenProcs,
4782 fileObj[2]);
4783 }
4784 }
4785 }
Tim Peters11b23062003-04-23 02:39:17 +00004786
Victor Stinnerd6f85422010-05-05 23:33:33 +00004787 /*
4788 * Clean up our localized references for the dictionary keys
4789 * and value since PyDict_SetItem will Py_INCREF any copies
4790 * that got placed in the dictionary.
4791 */
4792 Py_XDECREF(procObj);
4793 Py_XDECREF(fileObj[0]);
4794 Py_XDECREF(fileObj[1]);
4795 Py_XDECREF(fileObj[2]);
4796 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004797
Victor Stinnerd6f85422010-05-05 23:33:33 +00004798 /* Child is launched. */
4799 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004800}
4801
4802/*
4803 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4804 * exit code for the child process and return as a result of the close.
4805 *
4806 * This function uses the _PyPopenProcs dictionary in order to map the
4807 * input file pointer to information about the process that was
4808 * originally created by the popen* call that created the file pointer.
4809 * The dictionary uses the file pointer as a key (with one entry
4810 * inserted for each file returned by the original popen* call) and a
4811 * single list object as the value for all files from a single call.
4812 * The list object contains the Win32 process handle at [0], and a file
4813 * count at [1], which is initialized to the total number of file
4814 * handles using that list.
4815 *
4816 * This function closes whichever handle it is passed, and decrements
4817 * the file count in the dictionary for the process handle pointed to
4818 * by this file. On the last close (when the file count reaches zero),
4819 * this function will wait for the child process and then return its
4820 * exit code as the result of the close() operation. This permits the
4821 * files to be closed in any order - it is always the close() of the
4822 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004823 *
4824 * NOTE: This function is currently called with the GIL released.
4825 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004826 */
4827
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004828static int _PyPclose(FILE *file)
4829{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004830 int result;
4831 int exit_code;
4832 pid_t pipe_pid;
4833 PyObject *procObj, *pidObj, *intObj, *fileObj;
4834 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004835#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004836 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004837#endif
4838
Victor Stinnerd6f85422010-05-05 23:33:33 +00004839 /* Close the file handle first, to ensure it can't block the
4840 * child from exiting if it's the last handle.
4841 */
4842 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004843
4844#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004845 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004846#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004847 if (_PyPopenProcs)
4848 {
4849 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4850 (procObj = PyDict_GetItem(_PyPopenProcs,
4851 fileObj)) != NULL &&
4852 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4853 (intObj = PyList_GetItem(procObj,1)) != NULL)
4854 {
4855 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4856 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004857
Victor Stinnerd6f85422010-05-05 23:33:33 +00004858 if (file_count > 1)
4859 {
4860 /* Still other files referencing process */
4861 file_count--;
4862 PyList_SetItem(procObj,1,
4863 PyInt_FromLong((long) file_count));
4864 }
4865 else
4866 {
4867 /* Last file for this process */
4868 if (result != EOF &&
4869 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4870 {
4871 /* extract exit status */
4872 if (WIFEXITED(exit_code))
4873 {
4874 result = WEXITSTATUS(exit_code);
4875 }
4876 else
4877 {
4878 errno = EPIPE;
4879 result = -1;
4880 }
4881 }
4882 else
4883 {
4884 /* Indicate failure - this will cause the file object
4885 * to raise an I/O error and translate the last
4886 * error code from errno. We do have a problem with
4887 * last errors that overlap the normal errno table,
4888 * but that's a consistent problem with the file object.
4889 */
4890 result = -1;
4891 }
4892 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004893
Victor Stinnerd6f85422010-05-05 23:33:33 +00004894 /* Remove this file pointer from dictionary */
4895 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004896
Victor Stinnerd6f85422010-05-05 23:33:33 +00004897 if (PyDict_Size(_PyPopenProcs) == 0)
4898 {
4899 Py_DECREF(_PyPopenProcs);
4900 _PyPopenProcs = NULL;
4901 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004902
Victor Stinnerd6f85422010-05-05 23:33:33 +00004903 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004904
Victor Stinnerd6f85422010-05-05 23:33:33 +00004905 Py_XDECREF(fileObj);
4906 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004907
4908#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004909 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004910#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004911 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004912}
4913
4914#endif /* PYCC_??? */
4915
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004916#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004917
4918/*
4919 * Portable 'popen' replacement for Win32.
4920 *
4921 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4922 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004923 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 */
4925
4926#include <malloc.h>
4927#include <io.h>
4928#include <fcntl.h>
4929
4930/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4931#define POPEN_1 1
4932#define POPEN_2 2
4933#define POPEN_3 3
4934#define POPEN_4 4
4935
4936static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004937static int _PyPclose(FILE *file);
4938
4939/*
4940 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004941 * for use when retrieving the process exit code. See _PyPclose() below
4942 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004943 */
4944static PyObject *_PyPopenProcs = NULL;
4945
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004946
4947/* popen that works from a GUI.
4948 *
4949 * The result of this function is a pipe (file) connected to the
4950 * processes stdin or stdout, depending on the requested mode.
4951 */
4952
4953static PyObject *
4954posix_popen(PyObject *self, PyObject *args)
4955{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004956 PyObject *f;
4957 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004958
Victor Stinnerd6f85422010-05-05 23:33:33 +00004959 char *cmdstring;
4960 char *mode = "r";
4961 int bufsize = -1;
4962 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4963 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004964
Victor Stinnerd6f85422010-05-05 23:33:33 +00004965 if (*mode == 'r')
4966 tm = _O_RDONLY;
4967 else if (*mode != 'w') {
4968 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4969 return NULL;
4970 } else
4971 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004972
Victor Stinnerd6f85422010-05-05 23:33:33 +00004973 if (bufsize != -1) {
4974 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4975 return NULL;
4976 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004977
Victor Stinnerd6f85422010-05-05 23:33:33 +00004978 if (*(mode+1) == 't')
4979 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4980 else if (*(mode+1) == 'b')
4981 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4982 else
4983 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004984
Victor Stinnerd6f85422010-05-05 23:33:33 +00004985 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004986}
4987
4988/* Variation on win32pipe.popen
4989 *
4990 * The result of this function is a pipe (file) connected to the
4991 * process's stdin, and a pipe connected to the process's stdout.
4992 */
4993
4994static PyObject *
4995win32_popen2(PyObject *self, PyObject *args)
4996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004997 PyObject *f;
4998 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004999
Victor Stinnerd6f85422010-05-05 23:33:33 +00005000 char *cmdstring;
5001 char *mode = "t";
5002 int bufsize = -1;
5003 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5004 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005005
Victor Stinnerd6f85422010-05-05 23:33:33 +00005006 if (*mode == 't')
5007 tm = _O_TEXT;
5008 else if (*mode != 'b') {
5009 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5010 return NULL;
5011 } else
5012 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005013
Victor Stinnerd6f85422010-05-05 23:33:33 +00005014 if (bufsize != -1) {
5015 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5016 return NULL;
5017 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005018
Victor Stinnerd6f85422010-05-05 23:33:33 +00005019 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005020
Victor Stinnerd6f85422010-05-05 23:33:33 +00005021 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005022}
5023
5024/*
5025 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005026 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005027 * The result of this function is 3 pipes - the process's stdin,
5028 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005029 */
5030
5031static PyObject *
5032win32_popen3(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:popen3", &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, "popen3() 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, "popen3() 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_3);
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 win32pipe.popen
5063 *
Tim Peters5aa91602002-01-30 05:46:57 +00005064 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005065 * and stdout+stderr combined as a single pipe.
5066 */
5067
5068static PyObject *
5069win32_popen4(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:popen4", &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, "popen4() arg 2 must be 't' or 'b'");
5084 return NULL;
5085 } else
5086 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005087
Victor Stinnerd6f85422010-05-05 23:33:33 +00005088 if (bufsize != -1) {
5089 PyErr_SetString(PyExc_ValueError, "popen4() 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_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005094
Victor Stinnerd6f85422010-05-05 23:33:33 +00005095 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005096}
5097
Mark Hammond08501372001-01-31 07:30:29 +00005098static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005099_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005100 HANDLE hStdin,
5101 HANDLE hStdout,
5102 HANDLE hStderr,
5103 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005104{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005105 PROCESS_INFORMATION piProcInfo;
5106 STARTUPINFO siStartInfo;
5107 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5108 char *s1,*s2, *s3 = " /c ";
5109 const char *szConsoleSpawn = "w9xpopen.exe";
5110 int i;
5111 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005112
Victor Stinnerd6f85422010-05-05 23:33:33 +00005113 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5114 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005115
Victor Stinnerd6f85422010-05-05 23:33:33 +00005116 s1 = (char *)alloca(i);
5117 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5118 /* x < i, so x fits into an integer */
5119 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005120
Victor Stinnerd6f85422010-05-05 23:33:33 +00005121 /* Explicitly check if we are using COMMAND.COM. If we are
5122 * then use the w9xpopen hack.
5123 */
5124 comshell = s1 + x;
5125 while (comshell >= s1 && *comshell != '\\')
5126 --comshell;
5127 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005128
Victor Stinnerd6f85422010-05-05 23:33:33 +00005129 if (GetVersion() < 0x80000000 &&
5130 _stricmp(comshell, "command.com") != 0) {
5131 /* NT/2000 and not using command.com. */
5132 x = i + strlen(s3) + strlen(cmdstring) + 1;
5133 s2 = (char *)alloca(x);
5134 ZeroMemory(s2, x);
5135 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5136 }
5137 else {
5138 /*
5139 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5140 * the workaround listed in KB: Q150956
5141 */
5142 char modulepath[_MAX_PATH];
5143 struct stat statinfo;
5144 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5145 for (x = i = 0; modulepath[i]; i++)
5146 if (modulepath[i] == SEP)
5147 x = i+1;
5148 modulepath[x] = '\0';
5149 /* Create the full-name to w9xpopen, so we can test it exists */
5150 strncat(modulepath,
5151 szConsoleSpawn,
5152 (sizeof(modulepath)/sizeof(modulepath[0]))
5153 -strlen(modulepath));
5154 if (stat(modulepath, &statinfo) != 0) {
5155 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5156 /* Eeek - file-not-found - possibly an embedding
5157 situation - see if we can locate it in sys.prefix
5158 */
5159 strncpy(modulepath,
5160 Py_GetExecPrefix(),
5161 mplen);
5162 modulepath[mplen-1] = '\0';
5163 if (modulepath[strlen(modulepath)-1] != '\\')
5164 strcat(modulepath, "\\");
5165 strncat(modulepath,
5166 szConsoleSpawn,
5167 mplen-strlen(modulepath));
5168 /* No where else to look - raise an easily identifiable
5169 error, rather than leaving Windows to report
5170 "file not found" - as the user is probably blissfully
5171 unaware this shim EXE is used, and it will confuse them.
5172 (well, it confused me for a while ;-)
5173 */
5174 if (stat(modulepath, &statinfo) != 0) {
5175 PyErr_Format(PyExc_RuntimeError,
5176 "Can not locate '%s' which is needed "
5177 "for popen to work with your shell "
5178 "or platform.",
5179 szConsoleSpawn);
5180 return FALSE;
5181 }
5182 }
5183 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5184 strlen(modulepath) +
5185 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005186
Victor Stinnerd6f85422010-05-05 23:33:33 +00005187 s2 = (char *)alloca(x);
5188 ZeroMemory(s2, x);
5189 /* To maintain correct argument passing semantics,
5190 we pass the command-line as it stands, and allow
5191 quoting to be applied. w9xpopen.exe will then
5192 use its argv vector, and re-quote the necessary
5193 args for the ultimate child process.
5194 */
5195 PyOS_snprintf(
5196 s2, x,
5197 "\"%s\" %s%s%s",
5198 modulepath,
5199 s1,
5200 s3,
5201 cmdstring);
5202 /* Not passing CREATE_NEW_CONSOLE has been known to
5203 cause random failures on win9x. Specifically a
5204 dialog:
5205 "Your program accessed mem currently in use at xxx"
5206 and a hopeful warning about the stability of your
5207 system.
5208 Cost is Ctrl+C won't kill children, but anyone
5209 who cares can have a go!
5210 */
5211 dwProcessFlags |= CREATE_NEW_CONSOLE;
5212 }
5213 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214
Victor Stinnerd6f85422010-05-05 23:33:33 +00005215 /* Could be an else here to try cmd.exe / command.com in the path
5216 Now we'll just error out.. */
5217 else {
5218 PyErr_SetString(PyExc_RuntimeError,
5219 "Cannot locate a COMSPEC environment variable to "
5220 "use as the shell");
5221 return FALSE;
5222 }
Tim Peters5aa91602002-01-30 05:46:57 +00005223
Victor Stinnerd6f85422010-05-05 23:33:33 +00005224 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5225 siStartInfo.cb = sizeof(STARTUPINFO);
5226 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5227 siStartInfo.hStdInput = hStdin;
5228 siStartInfo.hStdOutput = hStdout;
5229 siStartInfo.hStdError = hStderr;
5230 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005231
Victor Stinnerd6f85422010-05-05 23:33:33 +00005232 if (CreateProcess(NULL,
5233 s2,
5234 NULL,
5235 NULL,
5236 TRUE,
5237 dwProcessFlags,
5238 NULL,
5239 NULL,
5240 &siStartInfo,
5241 &piProcInfo) ) {
5242 /* Close the handles now so anyone waiting is woken. */
5243 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005244
Victor Stinnerd6f85422010-05-05 23:33:33 +00005245 /* Return process handle */
5246 *hProcess = piProcInfo.hProcess;
5247 return TRUE;
5248 }
5249 win32_error("CreateProcess", s2);
5250 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005251}
5252
5253/* The following code is based off of KB: Q190351 */
5254
5255static PyObject *
5256_PyPopen(char *cmdstring, int mode, int n)
5257{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005258 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5259 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5260 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005261
Victor Stinnerd6f85422010-05-05 23:33:33 +00005262 SECURITY_ATTRIBUTES saAttr;
5263 BOOL fSuccess;
5264 int fd1, fd2, fd3;
5265 FILE *f1, *f2, *f3;
5266 long file_count;
5267 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005268
Victor Stinnerd6f85422010-05-05 23:33:33 +00005269 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5270 saAttr.bInheritHandle = TRUE;
5271 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005272
Victor Stinnerd6f85422010-05-05 23:33:33 +00005273 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5274 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005275
Victor Stinnerd6f85422010-05-05 23:33:33 +00005276 /* Create new output read handle and the input write handle. Set
5277 * the inheritance properties to FALSE. Otherwise, the child inherits
5278 * these handles; resulting in non-closeable handles to the pipes
5279 * being created. */
5280 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5281 GetCurrentProcess(), &hChildStdinWrDup, 0,
5282 FALSE,
5283 DUPLICATE_SAME_ACCESS);
5284 if (!fSuccess)
5285 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005286
Victor Stinnerd6f85422010-05-05 23:33:33 +00005287 /* Close the inheritable version of ChildStdin
5288 that we're using. */
5289 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005290
Victor Stinnerd6f85422010-05-05 23:33:33 +00005291 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5292 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005293
Victor Stinnerd6f85422010-05-05 23:33:33 +00005294 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5295 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5296 FALSE, DUPLICATE_SAME_ACCESS);
5297 if (!fSuccess)
5298 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005299
Victor Stinnerd6f85422010-05-05 23:33:33 +00005300 /* Close the inheritable version of ChildStdout
5301 that we're using. */
5302 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005303
Victor Stinnerd6f85422010-05-05 23:33:33 +00005304 if (n != POPEN_4) {
5305 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5306 return win32_error("CreatePipe", NULL);
5307 fSuccess = DuplicateHandle(GetCurrentProcess(),
5308 hChildStderrRd,
5309 GetCurrentProcess(),
5310 &hChildStderrRdDup, 0,
5311 FALSE, DUPLICATE_SAME_ACCESS);
5312 if (!fSuccess)
5313 return win32_error("DuplicateHandle", NULL);
5314 /* Close the inheritable version of ChildStdErr that we're using. */
5315 CloseHandle(hChildStderrRd);
5316 }
Tim Peters5aa91602002-01-30 05:46:57 +00005317
Victor Stinnerd6f85422010-05-05 23:33:33 +00005318 switch (n) {
5319 case POPEN_1:
5320 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5321 case _O_WRONLY | _O_TEXT:
5322 /* Case for writing to child Stdin in text mode. */
5323 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5324 f1 = _fdopen(fd1, "w");
5325 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5326 PyFile_SetBufSize(f, 0);
5327 /* We don't care about these pipes anymore, so close them. */
5328 CloseHandle(hChildStdoutRdDup);
5329 CloseHandle(hChildStderrRdDup);
5330 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005331
Victor Stinnerd6f85422010-05-05 23:33:33 +00005332 case _O_RDONLY | _O_TEXT:
5333 /* Case for reading from child Stdout in text mode. */
5334 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5335 f1 = _fdopen(fd1, "r");
5336 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5337 PyFile_SetBufSize(f, 0);
5338 /* We don't care about these pipes anymore, so close them. */
5339 CloseHandle(hChildStdinWrDup);
5340 CloseHandle(hChildStderrRdDup);
5341 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005342
Victor Stinnerd6f85422010-05-05 23:33:33 +00005343 case _O_RDONLY | _O_BINARY:
5344 /* Case for readinig from child Stdout in binary mode. */
5345 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5346 f1 = _fdopen(fd1, "rb");
5347 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5348 PyFile_SetBufSize(f, 0);
5349 /* We don't care about these pipes anymore, so close them. */
5350 CloseHandle(hChildStdinWrDup);
5351 CloseHandle(hChildStderrRdDup);
5352 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005353
Victor Stinnerd6f85422010-05-05 23:33:33 +00005354 case _O_WRONLY | _O_BINARY:
5355 /* Case for writing to child Stdin in binary mode. */
5356 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5357 f1 = _fdopen(fd1, "wb");
5358 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5359 PyFile_SetBufSize(f, 0);
5360 /* We don't care about these pipes anymore, so close them. */
5361 CloseHandle(hChildStdoutRdDup);
5362 CloseHandle(hChildStderrRdDup);
5363 break;
5364 }
5365 file_count = 1;
5366 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005367
Victor Stinnerd6f85422010-05-05 23:33:33 +00005368 case POPEN_2:
5369 case POPEN_4:
5370 {
5371 char *m1, *m2;
5372 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005373
Victor Stinnerd6f85422010-05-05 23:33:33 +00005374 if (mode & _O_TEXT) {
5375 m1 = "r";
5376 m2 = "w";
5377 } else {
5378 m1 = "rb";
5379 m2 = "wb";
5380 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005381
Victor Stinnerd6f85422010-05-05 23:33:33 +00005382 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5383 f1 = _fdopen(fd1, m2);
5384 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5385 f2 = _fdopen(fd2, m1);
5386 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5387 PyFile_SetBufSize(p1, 0);
5388 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5389 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005390
Victor Stinnerd6f85422010-05-05 23:33:33 +00005391 if (n != 4)
5392 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005393
Victor Stinnerd6f85422010-05-05 23:33:33 +00005394 f = PyTuple_Pack(2,p1,p2);
5395 Py_XDECREF(p1);
5396 Py_XDECREF(p2);
5397 file_count = 2;
5398 break;
5399 }
Tim Peters5aa91602002-01-30 05:46:57 +00005400
Victor Stinnerd6f85422010-05-05 23:33:33 +00005401 case POPEN_3:
5402 {
5403 char *m1, *m2;
5404 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005405
Victor Stinnerd6f85422010-05-05 23:33:33 +00005406 if (mode & _O_TEXT) {
5407 m1 = "r";
5408 m2 = "w";
5409 } else {
5410 m1 = "rb";
5411 m2 = "wb";
5412 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005413
Victor Stinnerd6f85422010-05-05 23:33:33 +00005414 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5415 f1 = _fdopen(fd1, m2);
5416 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5417 f2 = _fdopen(fd2, m1);
5418 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5419 f3 = _fdopen(fd3, m1);
5420 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5421 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5422 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5423 PyFile_SetBufSize(p1, 0);
5424 PyFile_SetBufSize(p2, 0);
5425 PyFile_SetBufSize(p3, 0);
5426 f = PyTuple_Pack(3,p1,p2,p3);
5427 Py_XDECREF(p1);
5428 Py_XDECREF(p2);
5429 Py_XDECREF(p3);
5430 file_count = 3;
5431 break;
5432 }
5433 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005434
Victor Stinnerd6f85422010-05-05 23:33:33 +00005435 if (n == POPEN_4) {
5436 if (!_PyPopenCreateProcess(cmdstring,
5437 hChildStdinRd,
5438 hChildStdoutWr,
5439 hChildStdoutWr,
5440 &hProcess))
5441 return NULL;
5442 }
5443 else {
5444 if (!_PyPopenCreateProcess(cmdstring,
5445 hChildStdinRd,
5446 hChildStdoutWr,
5447 hChildStderrWr,
5448 &hProcess))
5449 return NULL;
5450 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005451
Victor Stinnerd6f85422010-05-05 23:33:33 +00005452 /*
5453 * Insert the files we've created into the process dictionary
5454 * all referencing the list with the process handle and the
5455 * initial number of files (see description below in _PyPclose).
5456 * Since if _PyPclose later tried to wait on a process when all
5457 * handles weren't closed, it could create a deadlock with the
5458 * child, we spend some energy here to try to ensure that we
5459 * either insert all file handles into the dictionary or none
5460 * at all. It's a little clumsy with the various popen modes
5461 * and variable number of files involved.
5462 */
5463 if (!_PyPopenProcs) {
5464 _PyPopenProcs = PyDict_New();
5465 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005466
Victor Stinnerd6f85422010-05-05 23:33:33 +00005467 if (_PyPopenProcs) {
5468 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5469 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005470
Victor Stinnerd6f85422010-05-05 23:33:33 +00005471 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5472 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005473
Victor Stinnerd6f85422010-05-05 23:33:33 +00005474 procObj = PyList_New(2);
5475 hProcessObj = PyLong_FromVoidPtr(hProcess);
5476 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005477
Victor Stinnerd6f85422010-05-05 23:33:33 +00005478 if (procObj && hProcessObj && intObj) {
5479 PyList_SetItem(procObj,0,hProcessObj);
5480 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005481
Victor Stinnerd6f85422010-05-05 23:33:33 +00005482 fileObj[0] = PyLong_FromVoidPtr(f1);
5483 if (fileObj[0]) {
5484 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5485 fileObj[0],
5486 procObj);
5487 }
5488 if (file_count >= 2) {
5489 fileObj[1] = PyLong_FromVoidPtr(f2);
5490 if (fileObj[1]) {
5491 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5492 fileObj[1],
5493 procObj);
5494 }
5495 }
5496 if (file_count >= 3) {
5497 fileObj[2] = PyLong_FromVoidPtr(f3);
5498 if (fileObj[2]) {
5499 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5500 fileObj[2],
5501 procObj);
5502 }
5503 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005504
Victor Stinnerd6f85422010-05-05 23:33:33 +00005505 if (ins_rc[0] < 0 || !fileObj[0] ||
5506 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5507 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5508 /* Something failed - remove any dictionary
5509 * entries that did make it.
5510 */
5511 if (!ins_rc[0] && fileObj[0]) {
5512 PyDict_DelItem(_PyPopenProcs,
5513 fileObj[0]);
5514 }
5515 if (!ins_rc[1] && fileObj[1]) {
5516 PyDict_DelItem(_PyPopenProcs,
5517 fileObj[1]);
5518 }
5519 if (!ins_rc[2] && fileObj[2]) {
5520 PyDict_DelItem(_PyPopenProcs,
5521 fileObj[2]);
5522 }
5523 }
5524 }
Tim Peters5aa91602002-01-30 05:46:57 +00005525
Victor Stinnerd6f85422010-05-05 23:33:33 +00005526 /*
5527 * Clean up our localized references for the dictionary keys
5528 * and value since PyDict_SetItem will Py_INCREF any copies
5529 * that got placed in the dictionary.
5530 */
5531 Py_XDECREF(procObj);
5532 Py_XDECREF(fileObj[0]);
5533 Py_XDECREF(fileObj[1]);
5534 Py_XDECREF(fileObj[2]);
5535 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005536
Victor Stinnerd6f85422010-05-05 23:33:33 +00005537 /* Child is launched. Close the parents copy of those pipe
5538 * handles that only the child should have open. You need to
5539 * make sure that no handles to the write end of the output pipe
5540 * are maintained in this process or else the pipe will not close
5541 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005542
Victor Stinnerd6f85422010-05-05 23:33:33 +00005543 if (!CloseHandle(hChildStdinRd))
5544 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005545
Victor Stinnerd6f85422010-05-05 23:33:33 +00005546 if (!CloseHandle(hChildStdoutWr))
5547 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005548
Victor Stinnerd6f85422010-05-05 23:33:33 +00005549 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5550 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005551
Victor Stinnerd6f85422010-05-05 23:33:33 +00005552 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005553}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005554
5555/*
5556 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5557 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005558 *
5559 * This function uses the _PyPopenProcs dictionary in order to map the
5560 * input file pointer to information about the process that was
5561 * originally created by the popen* call that created the file pointer.
5562 * The dictionary uses the file pointer as a key (with one entry
5563 * inserted for each file returned by the original popen* call) and a
5564 * single list object as the value for all files from a single call.
5565 * The list object contains the Win32 process handle at [0], and a file
5566 * count at [1], which is initialized to the total number of file
5567 * handles using that list.
5568 *
5569 * This function closes whichever handle it is passed, and decrements
5570 * the file count in the dictionary for the process handle pointed to
5571 * by this file. On the last close (when the file count reaches zero),
5572 * this function will wait for the child process and then return its
5573 * exit code as the result of the close() operation. This permits the
5574 * files to be closed in any order - it is always the close() of the
5575 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005576 *
5577 * NOTE: This function is currently called with the GIL released.
5578 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005579 */
Tim Peters736aa322000-09-01 06:51:24 +00005580
Fredrik Lundh56055a42000-07-23 19:47:12 +00005581static int _PyPclose(FILE *file)
5582{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005583 int result;
5584 DWORD exit_code;
5585 HANDLE hProcess;
5586 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5587 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005588#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005589 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005590#endif
5591
Victor Stinnerd6f85422010-05-05 23:33:33 +00005592 /* Close the file handle first, to ensure it can't block the
5593 * child from exiting if it's the last handle.
5594 */
5595 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005596#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005597 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005598#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005599 if (_PyPopenProcs) {
5600 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5601 (procObj = PyDict_GetItem(_PyPopenProcs,
5602 fileObj)) != NULL &&
5603 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5604 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005605
Victor Stinnerd6f85422010-05-05 23:33:33 +00005606 hProcess = PyLong_AsVoidPtr(hProcessObj);
5607 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005608
Victor Stinnerd6f85422010-05-05 23:33:33 +00005609 if (file_count > 1) {
5610 /* Still other files referencing process */
5611 file_count--;
5612 PyList_SetItem(procObj,1,
5613 PyInt_FromLong(file_count));
5614 } else {
5615 /* Last file for this process */
5616 if (result != EOF &&
5617 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5618 GetExitCodeProcess(hProcess, &exit_code)) {
5619 /* Possible truncation here in 16-bit environments, but
5620 * real exit codes are just the lower byte in any event.
5621 */
5622 result = exit_code;
5623 } else {
5624 /* Indicate failure - this will cause the file object
5625 * to raise an I/O error and translate the last Win32
5626 * error code from errno. We do have a problem with
5627 * last errors that overlap the normal errno table,
5628 * but that's a consistent problem with the file object.
5629 */
5630 if (result != EOF) {
5631 /* If the error wasn't from the fclose(), then
5632 * set errno for the file object error handling.
5633 */
5634 errno = GetLastError();
5635 }
5636 result = -1;
5637 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005638
Victor Stinnerd6f85422010-05-05 23:33:33 +00005639 /* Free up the native handle at this point */
5640 CloseHandle(hProcess);
5641 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005642
Victor Stinnerd6f85422010-05-05 23:33:33 +00005643 /* Remove this file pointer from dictionary */
5644 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005645
Victor Stinnerd6f85422010-05-05 23:33:33 +00005646 if (PyDict_Size(_PyPopenProcs) == 0) {
5647 Py_DECREF(_PyPopenProcs);
5648 _PyPopenProcs = NULL;
5649 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005650
Victor Stinnerd6f85422010-05-05 23:33:33 +00005651 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005652
Victor Stinnerd6f85422010-05-05 23:33:33 +00005653 Py_XDECREF(fileObj);
5654 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005655
Tim Peters736aa322000-09-01 06:51:24 +00005656#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005657 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005658#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005659 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005660}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005661
5662#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005664posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005665{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005666 char *name;
5667 char *mode = "r";
5668 int bufsize = -1;
5669 FILE *fp;
5670 PyObject *f;
5671 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5672 return NULL;
5673 /* Strip mode of binary or text modifiers */
5674 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5675 mode = "r";
5676 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5677 mode = "w";
5678 Py_BEGIN_ALLOW_THREADS
5679 fp = popen(name, mode);
5680 Py_END_ALLOW_THREADS
5681 if (fp == NULL)
5682 return posix_error();
5683 f = PyFile_FromFile(fp, name, mode, pclose);
5684 if (f != NULL)
5685 PyFile_SetBufSize(f, bufsize);
5686 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005687}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005688
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005689#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005690#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005692
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005694PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005695"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005696Set the current process's user id.");
5697
Barry Warsaw53699e91996-12-10 23:23:01 +00005698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005699posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005700{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005701 long uid_arg;
5702 uid_t uid;
5703 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5704 return NULL;
5705 uid = uid_arg;
5706 if (uid != uid_arg) {
5707 PyErr_SetString(PyExc_OverflowError, "user id too big");
5708 return NULL;
5709 }
5710 if (setuid(uid) < 0)
5711 return posix_error();
5712 Py_INCREF(Py_None);
5713 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005714}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005715#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005717
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005718#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005720"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721Set the current process's effective user id.");
5722
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005723static PyObject *
5724posix_seteuid (PyObject *self, PyObject *args)
5725{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005726 long euid_arg;
5727 uid_t euid;
5728 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5729 return NULL;
5730 euid = euid_arg;
5731 if (euid != euid_arg) {
5732 PyErr_SetString(PyExc_OverflowError, "user id too big");
5733 return NULL;
5734 }
5735 if (seteuid(euid) < 0) {
5736 return posix_error();
5737 } else {
5738 Py_INCREF(Py_None);
5739 return Py_None;
5740 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005741}
5742#endif /* HAVE_SETEUID */
5743
5744#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005746"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Set the current process's effective group id.");
5748
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005749static PyObject *
5750posix_setegid (PyObject *self, PyObject *args)
5751{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005752 long egid_arg;
5753 gid_t egid;
5754 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5755 return NULL;
5756 egid = egid_arg;
5757 if (egid != egid_arg) {
5758 PyErr_SetString(PyExc_OverflowError, "group id too big");
5759 return NULL;
5760 }
5761 if (setegid(egid) < 0) {
5762 return posix_error();
5763 } else {
5764 Py_INCREF(Py_None);
5765 return Py_None;
5766 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005767}
5768#endif /* HAVE_SETEGID */
5769
5770#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005772"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005773Set the current process's real and effective user ids.");
5774
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005775static PyObject *
5776posix_setreuid (PyObject *self, PyObject *args)
5777{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005778 long ruid_arg, euid_arg;
5779 uid_t ruid, euid;
5780 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5781 return NULL;
5782 if (ruid_arg == -1)
5783 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5784 else
5785 ruid = ruid_arg; /* otherwise, assign from our long */
5786 if (euid_arg == -1)
5787 euid = (uid_t)-1;
5788 else
5789 euid = euid_arg;
5790 if ((euid_arg != -1 && euid != euid_arg) ||
5791 (ruid_arg != -1 && ruid != ruid_arg)) {
5792 PyErr_SetString(PyExc_OverflowError, "user id too big");
5793 return NULL;
5794 }
5795 if (setreuid(ruid, euid) < 0) {
5796 return posix_error();
5797 } else {
5798 Py_INCREF(Py_None);
5799 return Py_None;
5800 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005801}
5802#endif /* HAVE_SETREUID */
5803
5804#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005805PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005806"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005807Set the current process's real and effective group ids.");
5808
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005809static PyObject *
5810posix_setregid (PyObject *self, PyObject *args)
5811{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005812 long rgid_arg, egid_arg;
5813 gid_t rgid, egid;
5814 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5815 return NULL;
5816 if (rgid_arg == -1)
5817 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5818 else
5819 rgid = rgid_arg; /* otherwise, assign from our long */
5820 if (egid_arg == -1)
5821 egid = (gid_t)-1;
5822 else
5823 egid = egid_arg;
5824 if ((egid_arg != -1 && egid != egid_arg) ||
5825 (rgid_arg != -1 && rgid != rgid_arg)) {
5826 PyErr_SetString(PyExc_OverflowError, "group id too big");
5827 return NULL;
5828 }
5829 if (setregid(rgid, egid) < 0) {
5830 return posix_error();
5831 } else {
5832 Py_INCREF(Py_None);
5833 return Py_None;
5834 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005835}
5836#endif /* HAVE_SETREGID */
5837
Guido van Rossumb6775db1994-08-01 11:34:53 +00005838#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005840"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005841Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005842
Barry Warsaw53699e91996-12-10 23:23:01 +00005843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005844posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005845{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005846 long gid_arg;
5847 gid_t gid;
5848 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5849 return NULL;
5850 gid = gid_arg;
5851 if (gid != gid_arg) {
5852 PyErr_SetString(PyExc_OverflowError, "group id too big");
5853 return NULL;
5854 }
5855 if (setgid(gid) < 0)
5856 return posix_error();
5857 Py_INCREF(Py_None);
5858 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005859}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005860#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005861
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005862#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005864"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005866
5867static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005868posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005870 int i, len;
5871 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005872
Victor Stinnerd6f85422010-05-05 23:33:33 +00005873 if (!PySequence_Check(groups)) {
5874 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5875 return NULL;
5876 }
5877 len = PySequence_Size(groups);
5878 if (len > MAX_GROUPS) {
5879 PyErr_SetString(PyExc_ValueError, "too many groups");
5880 return NULL;
5881 }
5882 for(i = 0; i < len; i++) {
5883 PyObject *elem;
5884 elem = PySequence_GetItem(groups, i);
5885 if (!elem)
5886 return NULL;
5887 if (!PyInt_Check(elem)) {
5888 if (!PyLong_Check(elem)) {
5889 PyErr_SetString(PyExc_TypeError,
5890 "groups must be integers");
5891 Py_DECREF(elem);
5892 return NULL;
5893 } else {
5894 unsigned long x = PyLong_AsUnsignedLong(elem);
5895 if (PyErr_Occurred()) {
5896 PyErr_SetString(PyExc_TypeError,
5897 "group id too big");
5898 Py_DECREF(elem);
5899 return NULL;
5900 }
5901 grouplist[i] = x;
5902 /* read back to see if it fits in gid_t */
5903 if (grouplist[i] != x) {
5904 PyErr_SetString(PyExc_TypeError,
5905 "group id too big");
5906 Py_DECREF(elem);
5907 return NULL;
5908 }
5909 }
5910 } else {
5911 long x = PyInt_AsLong(elem);
5912 grouplist[i] = x;
5913 if (grouplist[i] != x) {
5914 PyErr_SetString(PyExc_TypeError,
5915 "group id too big");
5916 Py_DECREF(elem);
5917 return NULL;
5918 }
5919 }
5920 Py_DECREF(elem);
5921 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005922
Victor Stinnerd6f85422010-05-05 23:33:33 +00005923 if (setgroups(len, grouplist) < 0)
5924 return posix_error();
5925 Py_INCREF(Py_None);
5926 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005927}
5928#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005929
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005930#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005931static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005932wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005933{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005934 PyObject *result;
5935 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005936
Victor Stinnerd6f85422010-05-05 23:33:33 +00005937 if (pid == -1)
5938 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005939
Victor Stinnerd6f85422010-05-05 23:33:33 +00005940 if (struct_rusage == NULL) {
5941 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5942 if (m == NULL)
5943 return NULL;
5944 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5945 Py_DECREF(m);
5946 if (struct_rusage == NULL)
5947 return NULL;
5948 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005949
Victor Stinnerd6f85422010-05-05 23:33:33 +00005950 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5951 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5952 if (!result)
5953 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005954
5955#ifndef doubletime
5956#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5957#endif
5958
Victor Stinnerd6f85422010-05-05 23:33:33 +00005959 PyStructSequence_SET_ITEM(result, 0,
5960 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5961 PyStructSequence_SET_ITEM(result, 1,
5962 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00005963#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00005964 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5965 SET_INT(result, 2, ru->ru_maxrss);
5966 SET_INT(result, 3, ru->ru_ixrss);
5967 SET_INT(result, 4, ru->ru_idrss);
5968 SET_INT(result, 5, ru->ru_isrss);
5969 SET_INT(result, 6, ru->ru_minflt);
5970 SET_INT(result, 7, ru->ru_majflt);
5971 SET_INT(result, 8, ru->ru_nswap);
5972 SET_INT(result, 9, ru->ru_inblock);
5973 SET_INT(result, 10, ru->ru_oublock);
5974 SET_INT(result, 11, ru->ru_msgsnd);
5975 SET_INT(result, 12, ru->ru_msgrcv);
5976 SET_INT(result, 13, ru->ru_nsignals);
5977 SET_INT(result, 14, ru->ru_nvcsw);
5978 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00005979#undef SET_INT
5980
Victor Stinnerd6f85422010-05-05 23:33:33 +00005981 if (PyErr_Occurred()) {
5982 Py_DECREF(result);
5983 return NULL;
5984 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005985
Victor Stinnerd6f85422010-05-05 23:33:33 +00005986 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005987}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005988#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005989
5990#ifdef HAVE_WAIT3
5991PyDoc_STRVAR(posix_wait3__doc__,
5992"wait3(options) -> (pid, status, rusage)\n\n\
5993Wait for completion of a child process.");
5994
5995static PyObject *
5996posix_wait3(PyObject *self, PyObject *args)
5997{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005998 pid_t pid;
5999 int options;
6000 struct rusage ru;
6001 WAIT_TYPE status;
6002 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006003
Victor Stinnerd6f85422010-05-05 23:33:33 +00006004 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6005 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006006
Victor Stinnerd6f85422010-05-05 23:33:33 +00006007 Py_BEGIN_ALLOW_THREADS
6008 pid = wait3(&status, options, &ru);
6009 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006010
Victor Stinnerd6f85422010-05-05 23:33:33 +00006011 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006012}
6013#endif /* HAVE_WAIT3 */
6014
6015#ifdef HAVE_WAIT4
6016PyDoc_STRVAR(posix_wait4__doc__,
6017"wait4(pid, options) -> (pid, status, rusage)\n\n\
6018Wait for completion of a given child process.");
6019
6020static PyObject *
6021posix_wait4(PyObject *self, PyObject *args)
6022{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006023 pid_t pid;
6024 int options;
6025 struct rusage ru;
6026 WAIT_TYPE status;
6027 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006028
Victor Stinnerd6f85422010-05-05 23:33:33 +00006029 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6030 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006031
Victor Stinnerd6f85422010-05-05 23:33:33 +00006032 Py_BEGIN_ALLOW_THREADS
6033 pid = wait4(pid, &status, options, &ru);
6034 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006035
Victor Stinnerd6f85422010-05-05 23:33:33 +00006036 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006037}
6038#endif /* HAVE_WAIT4 */
6039
Guido van Rossumb6775db1994-08-01 11:34:53 +00006040#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006041PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006042"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006043Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006044
Barry Warsaw53699e91996-12-10 23:23:01 +00006045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006046posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006047{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006048 pid_t pid;
6049 int options;
6050 WAIT_TYPE status;
6051 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006052
Victor Stinnerd6f85422010-05-05 23:33:33 +00006053 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6054 return NULL;
6055 Py_BEGIN_ALLOW_THREADS
6056 pid = waitpid(pid, &status, options);
6057 Py_END_ALLOW_THREADS
6058 if (pid == -1)
6059 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006060
Victor Stinnerd6f85422010-05-05 23:33:33 +00006061 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006062}
6063
Tim Petersab034fa2002-02-01 11:27:43 +00006064#elif defined(HAVE_CWAIT)
6065
6066/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006068"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006069"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006070
6071static PyObject *
6072posix_waitpid(PyObject *self, PyObject *args)
6073{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006074 Py_intptr_t pid;
6075 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006076
Victor Stinnerd6f85422010-05-05 23:33:33 +00006077 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6078 return NULL;
6079 Py_BEGIN_ALLOW_THREADS
6080 pid = _cwait(&status, pid, options);
6081 Py_END_ALLOW_THREADS
6082 if (pid == -1)
6083 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006084
Victor Stinnerd6f85422010-05-05 23:33:33 +00006085 /* shift the status left a byte so this is more like the POSIX waitpid */
6086 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006087}
6088#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006089
Guido van Rossumad0ee831995-03-01 10:34:45 +00006090#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006091PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006092"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006093Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006094
Barry Warsaw53699e91996-12-10 23:23:01 +00006095static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006096posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006097{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006098 pid_t pid;
6099 WAIT_TYPE status;
6100 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006101
Victor Stinnerd6f85422010-05-05 23:33:33 +00006102 Py_BEGIN_ALLOW_THREADS
6103 pid = wait(&status);
6104 Py_END_ALLOW_THREADS
6105 if (pid == -1)
6106 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006107
Victor Stinnerd6f85422010-05-05 23:33:33 +00006108 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006109}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006110#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006113PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006114"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006116
Barry Warsaw53699e91996-12-10 23:23:01 +00006117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006119{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006120#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006121 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006122#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006123#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006124 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006125#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006126 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006127#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006128#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006129}
6130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006131
Guido van Rossumb6775db1994-08-01 11:34:53 +00006132#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006134"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006136
Barry Warsaw53699e91996-12-10 23:23:01 +00006137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006138posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006139{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006140 PyObject* v;
6141 char buf[MAXPATHLEN];
6142 char *path;
6143 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006144#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006145 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006146#endif
6147
Victor Stinnerd6f85422010-05-05 23:33:33 +00006148 if (!PyArg_ParseTuple(args, "et:readlink",
6149 Py_FileSystemDefaultEncoding, &path))
6150 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006151#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006152 v = PySequence_GetItem(args, 0);
6153 if (v == NULL) {
6154 PyMem_Free(path);
6155 return NULL;
6156 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006157
Victor Stinnerd6f85422010-05-05 23:33:33 +00006158 if (PyUnicode_Check(v)) {
6159 arg_is_unicode = 1;
6160 }
6161 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006162#endif
6163
Victor Stinnerd6f85422010-05-05 23:33:33 +00006164 Py_BEGIN_ALLOW_THREADS
6165 n = readlink(path, buf, (int) sizeof buf);
6166 Py_END_ALLOW_THREADS
6167 if (n < 0)
6168 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006169
Victor Stinnerd6f85422010-05-05 23:33:33 +00006170 PyMem_Free(path);
6171 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006172#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006173 if (arg_is_unicode) {
6174 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006175
Victor Stinnerd6f85422010-05-05 23:33:33 +00006176 w = PyUnicode_FromEncodedObject(v,
6177 Py_FileSystemDefaultEncoding,
6178 "strict");
6179 if (w != NULL) {
6180 Py_DECREF(v);
6181 v = w;
6182 }
6183 else {
6184 /* fall back to the original byte string, as
6185 discussed in patch #683592 */
6186 PyErr_Clear();
6187 }
6188 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006189#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006190 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006191}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006192#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006194
Guido van Rossumb6775db1994-08-01 11:34:53 +00006195#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006197"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006198Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006199
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006201posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006202{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006203 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006204}
6205#endif /* HAVE_SYMLINK */
6206
6207
6208#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006209#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6210static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006211system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006212{
6213 ULONG value = 0;
6214
6215 Py_BEGIN_ALLOW_THREADS
6216 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6217 Py_END_ALLOW_THREADS
6218
6219 return value;
6220}
6221
6222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006223posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006224{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006225 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006226 return Py_BuildValue("ddddd",
6227 (double)0 /* t.tms_utime / HZ */,
6228 (double)0 /* t.tms_stime / HZ */,
6229 (double)0 /* t.tms_cutime / HZ */,
6230 (double)0 /* t.tms_cstime / HZ */,
6231 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006232}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006233#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006234#define NEED_TICKS_PER_SECOND
6235static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006236static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006237posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006238{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006239 struct tms t;
6240 clock_t c;
6241 errno = 0;
6242 c = times(&t);
6243 if (c == (clock_t) -1)
6244 return posix_error();
6245 return Py_BuildValue("ddddd",
6246 (double)t.tms_utime / ticks_per_second,
6247 (double)t.tms_stime / ticks_per_second,
6248 (double)t.tms_cutime / ticks_per_second,
6249 (double)t.tms_cstime / ticks_per_second,
6250 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006251}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006252#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006253#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006254
6255
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006256#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006257#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006258static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006259posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006260{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006261 FILETIME create, exit, kernel, user;
6262 HANDLE hProc;
6263 hProc = GetCurrentProcess();
6264 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6265 /* The fields of a FILETIME structure are the hi and lo part
6266 of a 64-bit value expressed in 100 nanosecond units.
6267 1e7 is one second in such units; 1e-7 the inverse.
6268 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6269 */
6270 return Py_BuildValue(
6271 "ddddd",
6272 (double)(user.dwHighDateTime*429.4967296 +
6273 user.dwLowDateTime*1e-7),
6274 (double)(kernel.dwHighDateTime*429.4967296 +
6275 kernel.dwLowDateTime*1e-7),
6276 (double)0,
6277 (double)0,
6278 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006279}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006280#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006281
6282#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006283PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006284"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006286#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006288
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006289#ifdef HAVE_GETSID
6290PyDoc_STRVAR(posix_getsid__doc__,
6291"getsid(pid) -> sid\n\n\
6292Call the system call getsid().");
6293
6294static PyObject *
6295posix_getsid(PyObject *self, PyObject *args)
6296{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006297 pid_t pid;
6298 int sid;
6299 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6300 return NULL;
6301 sid = getsid(pid);
6302 if (sid < 0)
6303 return posix_error();
6304 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006305}
6306#endif /* HAVE_GETSID */
6307
6308
Guido van Rossumb6775db1994-08-01 11:34:53 +00006309#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006310PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006311"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006312Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006313
Barry Warsaw53699e91996-12-10 23:23:01 +00006314static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006315posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006316{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006317 if (setsid() < 0)
6318 return posix_error();
6319 Py_INCREF(Py_None);
6320 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006321}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006322#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006323
Guido van Rossumb6775db1994-08-01 11:34:53 +00006324#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006326"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Barry Warsaw53699e91996-12-10 23:23:01 +00006329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006330posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006331{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006332 pid_t pid;
6333 int pgrp;
6334 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6335 return NULL;
6336 if (setpgid(pid, pgrp) < 0)
6337 return posix_error();
6338 Py_INCREF(Py_None);
6339 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006340}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006341#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006343
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006346"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006347Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006348
Barry Warsaw53699e91996-12-10 23:23:01 +00006349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006350posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006351{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006352 int fd;
6353 pid_t pgid;
6354 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6355 return NULL;
6356 pgid = tcgetpgrp(fd);
6357 if (pgid < 0)
6358 return posix_error();
6359 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006360}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006363
Guido van Rossumb6775db1994-08-01 11:34:53 +00006364#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006366"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006367Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006368
Barry Warsaw53699e91996-12-10 23:23:01 +00006369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006370posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006371{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006372 int fd;
6373 pid_t pgid;
6374 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6375 return NULL;
6376 if (tcsetpgrp(fd, pgid) < 0)
6377 return posix_error();
6378 Py_INCREF(Py_None);
6379 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006380}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006381#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006382
Guido van Rossum687dd131993-05-17 08:34:16 +00006383/* Functions acting on file descriptors */
6384
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006385PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006386"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006387Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006388
Barry Warsaw53699e91996-12-10 23:23:01 +00006389static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006390posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006391{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006392 char *file = NULL;
6393 int flag;
6394 int mode = 0777;
6395 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006396
6397#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006398 PyUnicodeObject *po;
6399 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6400 Py_BEGIN_ALLOW_THREADS
6401 /* PyUnicode_AS_UNICODE OK without thread
6402 lock as it is a simple dereference. */
6403 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6404 Py_END_ALLOW_THREADS
6405 if (fd < 0)
6406 return posix_error();
6407 return PyInt_FromLong((long)fd);
6408 }
6409 /* Drop the argument parsing error as narrow strings
6410 are also valid. */
6411 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006412#endif
6413
Victor Stinnerd6f85422010-05-05 23:33:33 +00006414 if (!PyArg_ParseTuple(args, "eti|i",
6415 Py_FileSystemDefaultEncoding, &file,
6416 &flag, &mode))
6417 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006418
Victor Stinnerd6f85422010-05-05 23:33:33 +00006419 Py_BEGIN_ALLOW_THREADS
6420 fd = open(file, flag, mode);
6421 Py_END_ALLOW_THREADS
6422 if (fd < 0)
6423 return posix_error_with_allocated_filename(file);
6424 PyMem_Free(file);
6425 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006426}
6427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006429PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006430"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006432
Barry Warsaw53699e91996-12-10 23:23:01 +00006433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006434posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006435{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006436 int fd, res;
6437 if (!PyArg_ParseTuple(args, "i:close", &fd))
6438 return NULL;
6439 if (!_PyVerify_fd(fd))
6440 return posix_error();
6441 Py_BEGIN_ALLOW_THREADS
6442 res = close(fd);
6443 Py_END_ALLOW_THREADS
6444 if (res < 0)
6445 return posix_error();
6446 Py_INCREF(Py_None);
6447 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006448}
6449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006450
Victor Stinnerd6f85422010-05-05 23:33:33 +00006451PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006452"closerange(fd_low, fd_high)\n\n\
6453Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6454
6455static PyObject *
6456posix_closerange(PyObject *self, PyObject *args)
6457{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006458 int fd_from, fd_to, i;
6459 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6460 return NULL;
6461 Py_BEGIN_ALLOW_THREADS
6462 for (i = fd_from; i < fd_to; i++)
6463 if (_PyVerify_fd(i))
6464 close(i);
6465 Py_END_ALLOW_THREADS
6466 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006467}
6468
6469
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006470PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006471"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006472Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006473
Barry Warsaw53699e91996-12-10 23:23:01 +00006474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006475posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006476{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006477 int fd;
6478 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6479 return NULL;
6480 if (!_PyVerify_fd(fd))
6481 return posix_error();
6482 Py_BEGIN_ALLOW_THREADS
6483 fd = dup(fd);
6484 Py_END_ALLOW_THREADS
6485 if (fd < 0)
6486 return posix_error();
6487 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006488}
6489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006491PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006492"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006493Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006494
Barry Warsaw53699e91996-12-10 23:23:01 +00006495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006496posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006497{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006498 int fd, fd2, res;
6499 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6500 return NULL;
6501 if (!_PyVerify_fd_dup2(fd, fd2))
6502 return posix_error();
6503 Py_BEGIN_ALLOW_THREADS
6504 res = dup2(fd, fd2);
6505 Py_END_ALLOW_THREADS
6506 if (res < 0)
6507 return posix_error();
6508 Py_INCREF(Py_None);
6509 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006510}
6511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006513PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006514"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Barry Warsaw53699e91996-12-10 23:23:01 +00006517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006519{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006520 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006521#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006522 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006523#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006524 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006525#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006526 PyObject *posobj;
6527 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6528 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006529#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006530 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6531 switch (how) {
6532 case 0: how = SEEK_SET; break;
6533 case 1: how = SEEK_CUR; break;
6534 case 2: how = SEEK_END; break;
6535 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006536#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006537
6538#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006539 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006540#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006541 pos = PyLong_Check(posobj) ?
6542 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006543#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006544 if (PyErr_Occurred())
6545 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006546
Victor Stinnerd6f85422010-05-05 23:33:33 +00006547 if (!_PyVerify_fd(fd))
6548 return posix_error();
6549 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006550#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006551 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006552#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006553 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006554#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006555 Py_END_ALLOW_THREADS
6556 if (res < 0)
6557 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006558
6559#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006560 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006561#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006562 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006563#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006564}
6565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006567PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006568"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006569Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006570
Barry Warsaw53699e91996-12-10 23:23:01 +00006571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006572posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006573{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006574 int fd, size, n;
6575 PyObject *buffer;
6576 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6577 return NULL;
6578 if (size < 0) {
6579 errno = EINVAL;
6580 return posix_error();
6581 }
6582 buffer = PyString_FromStringAndSize((char *)NULL, size);
6583 if (buffer == NULL)
6584 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006585 if (!_PyVerify_fd(fd)) {
6586 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006587 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006588 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006589 Py_BEGIN_ALLOW_THREADS
6590 n = read(fd, PyString_AsString(buffer), size);
6591 Py_END_ALLOW_THREADS
6592 if (n < 0) {
6593 Py_DECREF(buffer);
6594 return posix_error();
6595 }
6596 if (n != size)
6597 _PyString_Resize(&buffer, n);
6598 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006599}
6600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006602PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006603"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006604Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006605
Barry Warsaw53699e91996-12-10 23:23:01 +00006606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006607posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006608{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006609 Py_buffer pbuf;
6610 int fd;
6611 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006612
Victor Stinnerd6f85422010-05-05 23:33:33 +00006613 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6614 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006615 if (!_PyVerify_fd(fd)) {
6616 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006617 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006618 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006619 Py_BEGIN_ALLOW_THREADS
6620 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6621 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006622 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006623 if (size < 0)
6624 return posix_error();
6625 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006626}
6627
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006628
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006629PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006630"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006631Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006632
Barry Warsaw53699e91996-12-10 23:23:01 +00006633static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006634posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006635{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006636 int fd;
6637 STRUCT_STAT st;
6638 int res;
6639 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6640 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006641#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006642 /* on OpenVMS we must ensure that all bytes are written to the file */
6643 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006644#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006645 if (!_PyVerify_fd(fd))
6646 return posix_error();
6647 Py_BEGIN_ALLOW_THREADS
6648 res = FSTAT(fd, &st);
6649 Py_END_ALLOW_THREADS
6650 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006651#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006652 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006653#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006654 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006655#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006656 }
Tim Peters5aa91602002-01-30 05:46:57 +00006657
Victor Stinnerd6f85422010-05-05 23:33:33 +00006658 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006659}
6660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006662PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006663"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006664Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006665
Barry Warsaw53699e91996-12-10 23:23:01 +00006666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006667posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006669 int fd;
6670 char *orgmode = "r";
6671 int bufsize = -1;
6672 FILE *fp;
6673 PyObject *f;
6674 char *mode;
6675 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6676 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006677
Victor Stinnerd6f85422010-05-05 23:33:33 +00006678 /* Sanitize mode. See fileobject.c */
6679 mode = PyMem_MALLOC(strlen(orgmode)+3);
6680 if (!mode) {
6681 PyErr_NoMemory();
6682 return NULL;
6683 }
6684 strcpy(mode, orgmode);
6685 if (_PyFile_SanitizeMode(mode)) {
6686 PyMem_FREE(mode);
6687 return NULL;
6688 }
6689 if (!_PyVerify_fd(fd))
6690 return posix_error();
6691 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006692#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006693 if (mode[0] == 'a') {
6694 /* try to make sure the O_APPEND flag is set */
6695 int flags;
6696 flags = fcntl(fd, F_GETFL);
6697 if (flags != -1)
6698 fcntl(fd, F_SETFL, flags | O_APPEND);
6699 fp = fdopen(fd, mode);
6700 if (fp == NULL && flags != -1)
6701 /* restore old mode if fdopen failed */
6702 fcntl(fd, F_SETFL, flags);
6703 } else {
6704 fp = fdopen(fd, mode);
6705 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006706#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006707 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006708#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006709 Py_END_ALLOW_THREADS
6710 PyMem_FREE(mode);
6711 if (fp == NULL)
6712 return posix_error();
6713 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6714 if (f != NULL)
6715 PyFile_SetBufSize(f, bufsize);
6716 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006717}
6718
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006719PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006720"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006721Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006722connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006723
6724static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006725posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006726{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006727 int fd;
6728 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6729 return NULL;
6730 if (!_PyVerify_fd(fd))
6731 return PyBool_FromLong(0);
6732 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006733}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006734
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006735#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006736PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006737"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006738Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006739
Barry Warsaw53699e91996-12-10 23:23:01 +00006740static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006741posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006742{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006743#if defined(PYOS_OS2)
6744 HFILE read, write;
6745 APIRET rc;
6746
Victor Stinnerd6f85422010-05-05 23:33:33 +00006747 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006748 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006749 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006750 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006751 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006752
6753 return Py_BuildValue("(ii)", read, write);
6754#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006755#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006756 int fds[2];
6757 int res;
6758 Py_BEGIN_ALLOW_THREADS
6759 res = pipe(fds);
6760 Py_END_ALLOW_THREADS
6761 if (res != 0)
6762 return posix_error();
6763 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006764#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006765 HANDLE read, write;
6766 int read_fd, write_fd;
6767 BOOL ok;
6768 Py_BEGIN_ALLOW_THREADS
6769 ok = CreatePipe(&read, &write, NULL, 0);
6770 Py_END_ALLOW_THREADS
6771 if (!ok)
6772 return win32_error("CreatePipe", NULL);
6773 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6774 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6775 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006776#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006777#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006778}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006779#endif /* HAVE_PIPE */
6780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006781
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006782#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006783PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006784"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006785Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006786
Barry Warsaw53699e91996-12-10 23:23:01 +00006787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006788posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006789{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006790 char *filename;
6791 int mode = 0666;
6792 int res;
6793 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6794 return NULL;
6795 Py_BEGIN_ALLOW_THREADS
6796 res = mkfifo(filename, mode);
6797 Py_END_ALLOW_THREADS
6798 if (res < 0)
6799 return posix_error();
6800 Py_INCREF(Py_None);
6801 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006802}
6803#endif
6804
6805
Neal Norwitz11690112002-07-30 01:08:28 +00006806#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006807PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006808"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006809Create a filesystem node (file, device special file or named pipe)\n\
6810named filename. mode specifies both the permissions to use and the\n\
6811type of node to be created, being combined (bitwise OR) with one of\n\
6812S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006813device defines the newly created device special file (probably using\n\
6814os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006815
6816
6817static PyObject *
6818posix_mknod(PyObject *self, PyObject *args)
6819{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006820 char *filename;
6821 int mode = 0600;
6822 int device = 0;
6823 int res;
6824 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6825 return NULL;
6826 Py_BEGIN_ALLOW_THREADS
6827 res = mknod(filename, mode, device);
6828 Py_END_ALLOW_THREADS
6829 if (res < 0)
6830 return posix_error();
6831 Py_INCREF(Py_None);
6832 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006833}
6834#endif
6835
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006836#ifdef HAVE_DEVICE_MACROS
6837PyDoc_STRVAR(posix_major__doc__,
6838"major(device) -> major number\n\
6839Extracts a device major number from a raw device number.");
6840
6841static PyObject *
6842posix_major(PyObject *self, PyObject *args)
6843{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006844 int device;
6845 if (!PyArg_ParseTuple(args, "i:major", &device))
6846 return NULL;
6847 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006848}
6849
6850PyDoc_STRVAR(posix_minor__doc__,
6851"minor(device) -> minor number\n\
6852Extracts a device minor number from a raw device number.");
6853
6854static PyObject *
6855posix_minor(PyObject *self, PyObject *args)
6856{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006857 int device;
6858 if (!PyArg_ParseTuple(args, "i:minor", &device))
6859 return NULL;
6860 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006861}
6862
6863PyDoc_STRVAR(posix_makedev__doc__,
6864"makedev(major, minor) -> device number\n\
6865Composes a raw device number from the major and minor device numbers.");
6866
6867static PyObject *
6868posix_makedev(PyObject *self, PyObject *args)
6869{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006870 int major, minor;
6871 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6872 return NULL;
6873 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006874}
6875#endif /* device macros */
6876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006877
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006878#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006879PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006880"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006881Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006882
Barry Warsaw53699e91996-12-10 23:23:01 +00006883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006884posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006885{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006886 int fd;
6887 off_t length;
6888 int res;
6889 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006890
Victor Stinnerd6f85422010-05-05 23:33:33 +00006891 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6892 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006893
6894#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006895 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006896#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006897 length = PyLong_Check(lenobj) ?
6898 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006899#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006900 if (PyErr_Occurred())
6901 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006902
Victor Stinnerd6f85422010-05-05 23:33:33 +00006903 Py_BEGIN_ALLOW_THREADS
6904 res = ftruncate(fd, length);
6905 Py_END_ALLOW_THREADS
6906 if (res < 0)
6907 return posix_error();
6908 Py_INCREF(Py_None);
6909 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006910}
6911#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006912
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006913#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006914PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006915"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006916Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006917
Fred Drake762e2061999-08-26 17:23:54 +00006918/* Save putenv() parameters as values here, so we can collect them when they
6919 * get re-set with another call for the same key. */
6920static PyObject *posix_putenv_garbage;
6921
Tim Peters5aa91602002-01-30 05:46:57 +00006922static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006923posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006924{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006925 char *s1, *s2;
6926 char *newenv;
6927 PyObject *newstr;
6928 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006929
Victor Stinnerd6f85422010-05-05 23:33:33 +00006930 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6931 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006932
6933#if defined(PYOS_OS2)
6934 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6935 APIRET rc;
6936
Guido van Rossumd48f2521997-12-05 22:19:34 +00006937 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6938 if (rc != NO_ERROR)
6939 return os2_error(rc);
6940
6941 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6942 APIRET rc;
6943
Guido van Rossumd48f2521997-12-05 22:19:34 +00006944 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6945 if (rc != NO_ERROR)
6946 return os2_error(rc);
6947 } else {
6948#endif
6949
Victor Stinnerd6f85422010-05-05 23:33:33 +00006950 /* XXX This can leak memory -- not easy to fix :-( */
6951 len = strlen(s1) + strlen(s2) + 2;
6952 /* len includes space for a trailing \0; the size arg to
6953 PyString_FromStringAndSize does not count that */
6954 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6955 if (newstr == NULL)
6956 return PyErr_NoMemory();
6957 newenv = PyString_AS_STRING(newstr);
6958 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6959 if (putenv(newenv)) {
6960 Py_DECREF(newstr);
6961 posix_error();
6962 return NULL;
6963 }
6964 /* Install the first arg and newstr in posix_putenv_garbage;
6965 * this will cause previous value to be collected. This has to
6966 * happen after the real putenv() call because the old value
6967 * was still accessible until then. */
6968 if (PyDict_SetItem(posix_putenv_garbage,
6969 PyTuple_GET_ITEM(args, 0), newstr)) {
6970 /* really not much we can do; just leak */
6971 PyErr_Clear();
6972 }
6973 else {
6974 Py_DECREF(newstr);
6975 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006976
6977#if defined(PYOS_OS2)
6978 }
6979#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006980 Py_INCREF(Py_None);
6981 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006982}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006983#endif /* putenv */
6984
Guido van Rossumc524d952001-10-19 01:31:59 +00006985#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006986PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006987"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006988Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006989
6990static PyObject *
6991posix_unsetenv(PyObject *self, PyObject *args)
6992{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006993 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006994
Victor Stinnerd6f85422010-05-05 23:33:33 +00006995 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6996 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00006997
Victor Stinnerd6f85422010-05-05 23:33:33 +00006998 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006999
Victor Stinnerd6f85422010-05-05 23:33:33 +00007000 /* Remove the key from posix_putenv_garbage;
7001 * this will cause it to be collected. This has to
7002 * happen after the real unsetenv() call because the
7003 * old value was still accessible until then.
7004 */
7005 if (PyDict_DelItem(posix_putenv_garbage,
7006 PyTuple_GET_ITEM(args, 0))) {
7007 /* really not much we can do; just leak */
7008 PyErr_Clear();
7009 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007010
Victor Stinnerd6f85422010-05-05 23:33:33 +00007011 Py_INCREF(Py_None);
7012 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007013}
7014#endif /* unsetenv */
7015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007016PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007017"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007018Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007019
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007021posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007022{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007023 int code;
7024 char *message;
7025 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7026 return NULL;
7027 message = strerror(code);
7028 if (message == NULL) {
7029 PyErr_SetString(PyExc_ValueError,
7030 "strerror() argument out of range");
7031 return NULL;
7032 }
7033 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007034}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007035
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007036
Guido van Rossumc9641791998-08-04 15:26:23 +00007037#ifdef HAVE_SYS_WAIT_H
7038
Fred Drake106c1a02002-04-23 15:58:02 +00007039#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007040PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007041"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007042Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007043
7044static PyObject *
7045posix_WCOREDUMP(PyObject *self, PyObject *args)
7046{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007047 WAIT_TYPE status;
7048 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007049
Victor Stinnerd6f85422010-05-05 23:33:33 +00007050 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7051 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007052
Victor Stinnerd6f85422010-05-05 23:33:33 +00007053 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007054}
7055#endif /* WCOREDUMP */
7056
7057#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007058PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007059"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007060Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007061job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007062
7063static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007064posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007065{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007066 WAIT_TYPE status;
7067 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007068
Victor Stinnerd6f85422010-05-05 23:33:33 +00007069 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7070 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007071
Victor Stinnerd6f85422010-05-05 23:33:33 +00007072 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007073}
7074#endif /* WIFCONTINUED */
7075
Guido van Rossumc9641791998-08-04 15:26:23 +00007076#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007077PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007078"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007079Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007080
7081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007082posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007083{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007084 WAIT_TYPE status;
7085 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007086
Victor Stinnerd6f85422010-05-05 23:33:33 +00007087 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7088 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007089
Victor Stinnerd6f85422010-05-05 23:33:33 +00007090 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007091}
7092#endif /* WIFSTOPPED */
7093
7094#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007095PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007096"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007097Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007098
7099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007100posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007101{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007102 WAIT_TYPE status;
7103 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007104
Victor Stinnerd6f85422010-05-05 23:33:33 +00007105 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007107
Victor Stinnerd6f85422010-05-05 23:33:33 +00007108 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007109}
7110#endif /* WIFSIGNALED */
7111
7112#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007113PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007114"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007115Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007116system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007117
7118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007119posix_WIFEXITED(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:WIFEXITED", &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(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007128}
7129#endif /* WIFEXITED */
7130
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007131#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007132PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007133"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007134Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007135
7136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007137posix_WEXITSTATUS(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:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007144
Victor Stinnerd6f85422010-05-05 23:33:33 +00007145 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007146}
7147#endif /* WEXITSTATUS */
7148
7149#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007150PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007151"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007152Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007153value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007154
7155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007156posix_WTERMSIG(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:WTERMSIG", &WAIT_STATUS_INT(status)))
7162 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007163
Victor Stinnerd6f85422010-05-05 23:33:33 +00007164 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007165}
7166#endif /* WTERMSIG */
7167
7168#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007170"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007171Return the signal that stopped the process that provided\n\
7172the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007173
7174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007175posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007176{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007177 WAIT_TYPE status;
7178 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007179
Victor Stinnerd6f85422010-05-05 23:33:33 +00007180 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7181 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007182
Victor Stinnerd6f85422010-05-05 23:33:33 +00007183 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007184}
7185#endif /* WSTOPSIG */
7186
7187#endif /* HAVE_SYS_WAIT_H */
7188
7189
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007190#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007191#ifdef _SCO_DS
7192/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7193 needed definitions in sys/statvfs.h */
7194#define _SVID3
7195#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007196#include <sys/statvfs.h>
7197
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007198static PyObject*
7199_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007200 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7201 if (v == NULL)
7202 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007203
7204#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007205 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7206 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7207 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7208 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7209 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7210 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7211 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7212 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7213 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7214 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007215#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007216 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7217 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7218 PyStructSequence_SET_ITEM(v, 2,
7219 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7220 PyStructSequence_SET_ITEM(v, 3,
7221 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7222 PyStructSequence_SET_ITEM(v, 4,
7223 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7224 PyStructSequence_SET_ITEM(v, 5,
7225 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7226 PyStructSequence_SET_ITEM(v, 6,
7227 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7228 PyStructSequence_SET_ITEM(v, 7,
7229 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7230 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7231 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007232#endif
7233
Victor Stinnerd6f85422010-05-05 23:33:33 +00007234 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007235}
7236
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007237PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007238"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007239Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007240
7241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007242posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007243{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007244 int fd, res;
7245 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007246
Victor Stinnerd6f85422010-05-05 23:33:33 +00007247 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7248 return NULL;
7249 Py_BEGIN_ALLOW_THREADS
7250 res = fstatvfs(fd, &st);
7251 Py_END_ALLOW_THREADS
7252 if (res != 0)
7253 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007254
Victor Stinnerd6f85422010-05-05 23:33:33 +00007255 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007256}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007257#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007258
7259
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007260#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007261#include <sys/statvfs.h>
7262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007263PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007264"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007265Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007266
7267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007268posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007269{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007270 char *path;
7271 int res;
7272 struct statvfs st;
7273 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7274 return NULL;
7275 Py_BEGIN_ALLOW_THREADS
7276 res = statvfs(path, &st);
7277 Py_END_ALLOW_THREADS
7278 if (res != 0)
7279 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007280
Victor Stinnerd6f85422010-05-05 23:33:33 +00007281 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007282}
7283#endif /* HAVE_STATVFS */
7284
7285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007286#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007287PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007288"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007289Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007290The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007291or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007292
7293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007294posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007295{
7296 PyObject *result = NULL;
7297 char *dir = NULL;
7298 char *pfx = NULL;
7299 char *name;
7300
7301 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007302 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007303
7304 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007305 "tempnam is a potential security risk to your program") < 0)
7306 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007307
Antoine Pitroub0614612011-01-02 20:04:52 +00007308 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7309 "use the tempfile module", 1) < 0)
7310 return NULL;
7311
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007312#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007313 name = _tempnam(dir, pfx);
7314#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007315 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007316#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007317 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007318 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007319 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007320 free(name);
7321 return result;
7322}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007323#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007324
7325
7326#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007327PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007328"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007329Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007330
7331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007332posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007333{
7334 FILE *fp;
7335
Antoine Pitroub0614612011-01-02 20:04:52 +00007336 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7337 "use the tempfile module", 1) < 0)
7338 return NULL;
7339
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007340 fp = tmpfile();
7341 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007342 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007343 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007344}
7345#endif
7346
7347
7348#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007349PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007350"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007351Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007352
7353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007354posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007355{
7356 char buffer[L_tmpnam];
7357 char *name;
7358
Skip Montanaro95618b52001-08-18 18:52:10 +00007359 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007360 "tmpnam is a potential security risk to your program") < 0)
7361 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007362
Antoine Pitroub0614612011-01-02 20:04:52 +00007363 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7364 "use the tempfile module", 1) < 0)
7365 return NULL;
7366
Greg Wardb48bc172000-03-01 21:51:56 +00007367#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007368 name = tmpnam_r(buffer);
7369#else
7370 name = tmpnam(buffer);
7371#endif
7372 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007373 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007374#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007375 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007376#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007377 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007378#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007379 );
7380 PyErr_SetObject(PyExc_OSError, err);
7381 Py_XDECREF(err);
7382 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007383 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007384 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007385}
7386#endif
7387
7388
Fred Drakec9680921999-12-13 16:37:25 +00007389/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7390 * It maps strings representing configuration variable names to
7391 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007392 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007393 * rarely-used constants. There are three separate tables that use
7394 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007395 *
7396 * This code is always included, even if none of the interfaces that
7397 * need it are included. The #if hackery needed to avoid it would be
7398 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007399 */
7400struct constdef {
7401 char *name;
7402 long value;
7403};
7404
Fred Drake12c6e2d1999-12-14 21:25:03 +00007405static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007406conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007407 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007408{
7409 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007410 *valuep = PyInt_AS_LONG(arg);
7411 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007412 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007413 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007414 /* look up the value in the table using a binary search */
7415 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007416 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007417 size_t hi = tablesize;
7418 int cmp;
7419 char *confname = PyString_AS_STRING(arg);
7420 while (lo < hi) {
7421 mid = (lo + hi) / 2;
7422 cmp = strcmp(confname, table[mid].name);
7423 if (cmp < 0)
7424 hi = mid;
7425 else if (cmp > 0)
7426 lo = mid + 1;
7427 else {
7428 *valuep = table[mid].value;
7429 return 1;
7430 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007431 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007432 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007433 }
7434 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007435 PyErr_SetString(PyExc_TypeError,
7436 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007437 return 0;
7438}
7439
7440
7441#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7442static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007443#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007444 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007445#endif
7446#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007447 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007448#endif
Fred Drakec9680921999-12-13 16:37:25 +00007449#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007450 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007451#endif
7452#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007453 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007454#endif
7455#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007456 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007457#endif
7458#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007459 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007460#endif
7461#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007462 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007463#endif
7464#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007465 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007466#endif
7467#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007468 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007469#endif
7470#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007471 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007472#endif
7473#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007474 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007475#endif
7476#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007477 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007478#endif
7479#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007480 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007481#endif
7482#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007483 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007484#endif
7485#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007486 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007487#endif
7488#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007489 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007490#endif
7491#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007492 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007493#endif
7494};
7495
Fred Drakec9680921999-12-13 16:37:25 +00007496static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007497conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007498{
7499 return conv_confname(arg, valuep, posix_constants_pathconf,
7500 sizeof(posix_constants_pathconf)
7501 / sizeof(struct constdef));
7502}
7503#endif
7504
7505#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007506PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007507"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007508Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007509If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007510
7511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007512posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007513{
7514 PyObject *result = NULL;
7515 int name, fd;
7516
Fred Drake12c6e2d1999-12-14 21:25:03 +00007517 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7518 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007519 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007520
Stefan Krah93f7a322010-11-26 17:35:50 +00007521 errno = 0;
7522 limit = fpathconf(fd, name);
7523 if (limit == -1 && errno != 0)
7524 posix_error();
7525 else
7526 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007527 }
7528 return result;
7529}
7530#endif
7531
7532
7533#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007534PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007535"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007536Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007537If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007538
7539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007540posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007541{
7542 PyObject *result = NULL;
7543 int name;
7544 char *path;
7545
7546 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7547 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007548 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007549
Victor Stinnerd6f85422010-05-05 23:33:33 +00007550 errno = 0;
7551 limit = pathconf(path, name);
7552 if (limit == -1 && errno != 0) {
7553 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007554 /* could be a path or name problem */
7555 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007556 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007557 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007558 }
7559 else
7560 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007561 }
7562 return result;
7563}
7564#endif
7565
7566#ifdef HAVE_CONFSTR
7567static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007568#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007569 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007570#endif
7571#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007572 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007573#endif
7574#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007575 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007576#endif
7577#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007578 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007579#endif
7580#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007581 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007582#endif
Fred Drakec9680921999-12-13 16:37:25 +00007583#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007584 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007585#endif
7586#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007587 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007588#endif
7589#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007590 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007591#endif
7592#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007593 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007594#endif
7595#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007596 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007597#endif
7598#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007599 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007600#endif
7601#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007602 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007603#endif
7604#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007605 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007606#endif
Fred Draked86ed291999-12-15 15:34:33 +00007607#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007608 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007609#endif
Fred Drakec9680921999-12-13 16:37:25 +00007610#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007611 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007612#endif
Fred Draked86ed291999-12-15 15:34:33 +00007613#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007614 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007615#endif
7616#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007617 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007618#endif
7619#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007620 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007621#endif
7622#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007623 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007624#endif
Fred Drakec9680921999-12-13 16:37:25 +00007625#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007626 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007627#endif
7628#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007629 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007630#endif
7631#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007632 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007633#endif
7634#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007635 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007636#endif
7637#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007638 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007639#endif
7640#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007641 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007642#endif
7643#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007644 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007645#endif
7646#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007647 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007648#endif
7649#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007650 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007651#endif
7652#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007653 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007654#endif
7655#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007656 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007657#endif
7658#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007659 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007660#endif
7661#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007662 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007663#endif
7664#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007665 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007666#endif
7667#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007668 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007669#endif
7670#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007671 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007672#endif
Fred Draked86ed291999-12-15 15:34:33 +00007673#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007674 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007675#endif
7676#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007677 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007678#endif
7679#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007680 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007681#endif
7682#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007683 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007684#endif
7685#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007686 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007687#endif
7688#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007689 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007690#endif
7691#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007692 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007693#endif
7694#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007696#endif
7697#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007698 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007699#endif
7700#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007701 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007702#endif
7703#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007704 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007705#endif
7706#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007708#endif
7709#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007711#endif
Fred Drakec9680921999-12-13 16:37:25 +00007712};
7713
7714static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007715conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007716{
7717 return conv_confname(arg, valuep, posix_constants_confstr,
7718 sizeof(posix_constants_confstr)
7719 / sizeof(struct constdef));
7720}
7721
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007722PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007723"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007724Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007725
7726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007727posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007728{
7729 PyObject *result = NULL;
7730 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007731 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007732
7733 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007735
Victor Stinnerd6f85422010-05-05 23:33:33 +00007736 errno = 0;
7737 len = confstr(name, buffer, sizeof(buffer));
7738 if (len == 0) {
7739 if (errno) {
7740 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007741 }
7742 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007743 result = Py_None;
7744 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007745 }
7746 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007747 else {
7748 if ((unsigned int)len >= sizeof(buffer)) {
7749 result = PyString_FromStringAndSize(NULL, len-1);
7750 if (result != NULL)
7751 confstr(name, PyString_AS_STRING(result), len);
7752 }
7753 else
7754 result = PyString_FromStringAndSize(buffer, len-1);
7755 }
7756 }
Fred Drakec9680921999-12-13 16:37:25 +00007757 return result;
7758}
7759#endif
7760
7761
7762#ifdef HAVE_SYSCONF
7763static struct constdef posix_constants_sysconf[] = {
7764#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007765 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007766#endif
7767#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007768 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007769#endif
7770#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007771 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007772#endif
7773#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007774 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007775#endif
7776#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007777 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007778#endif
7779#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007780 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007781#endif
7782#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007783 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007784#endif
7785#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007786 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007787#endif
7788#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007789 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007790#endif
7791#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007792 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007793#endif
Fred Draked86ed291999-12-15 15:34:33 +00007794#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007795 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007796#endif
7797#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007798 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007799#endif
Fred Drakec9680921999-12-13 16:37:25 +00007800#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007801 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007802#endif
Fred Drakec9680921999-12-13 16:37:25 +00007803#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007804 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007805#endif
7806#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007807 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007808#endif
7809#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007810 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007811#endif
7812#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007813 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007814#endif
7815#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007816 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007817#endif
Fred Draked86ed291999-12-15 15:34:33 +00007818#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007819 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007820#endif
Fred Drakec9680921999-12-13 16:37:25 +00007821#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007822 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007823#endif
7824#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007825 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007826#endif
7827#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007828 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007829#endif
7830#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007831 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007832#endif
7833#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007834 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007835#endif
Fred Draked86ed291999-12-15 15:34:33 +00007836#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007837 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007838#endif
Fred Drakec9680921999-12-13 16:37:25 +00007839#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007840 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007841#endif
7842#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007843 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007844#endif
7845#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007846 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007847#endif
7848#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007849 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007850#endif
7851#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007852 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007853#endif
7854#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007855 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007856#endif
7857#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007858 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007859#endif
7860#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007861 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007862#endif
7863#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007864 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007865#endif
7866#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007867 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007868#endif
7869#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007870 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007871#endif
7872#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007873 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007874#endif
7875#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007876 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007877#endif
7878#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007879 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007880#endif
7881#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007882 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007883#endif
7884#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007885 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007886#endif
7887#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007888 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007889#endif
7890#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007891 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007892#endif
7893#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007894 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007895#endif
7896#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007897 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007898#endif
7899#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007900 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007901#endif
7902#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007903 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007904#endif
7905#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007906 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007907#endif
Fred Draked86ed291999-12-15 15:34:33 +00007908#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007909 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007910#endif
Fred Drakec9680921999-12-13 16:37:25 +00007911#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007912 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007913#endif
7914#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007915 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007916#endif
7917#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007918 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007919#endif
Fred Draked86ed291999-12-15 15:34:33 +00007920#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007921 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007922#endif
Fred Drakec9680921999-12-13 16:37:25 +00007923#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007924 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007925#endif
Fred Draked86ed291999-12-15 15:34:33 +00007926#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007927 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007928#endif
7929#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007930 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007931#endif
Fred Drakec9680921999-12-13 16:37:25 +00007932#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007933 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007934#endif
7935#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007936 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007937#endif
7938#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007939 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007940#endif
7941#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007942 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007943#endif
Fred Draked86ed291999-12-15 15:34:33 +00007944#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007945 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007946#endif
Fred Drakec9680921999-12-13 16:37:25 +00007947#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007948 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007949#endif
7950#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007951 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007952#endif
7953#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007954 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007955#endif
7956#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007957 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007958#endif
7959#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007960 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007961#endif
7962#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007963 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007964#endif
7965#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00007966 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007967#endif
Fred Draked86ed291999-12-15 15:34:33 +00007968#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007969 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007970#endif
Fred Drakec9680921999-12-13 16:37:25 +00007971#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007972 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007973#endif
7974#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007975 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007976#endif
Fred Draked86ed291999-12-15 15:34:33 +00007977#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007978 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007979#endif
Fred Drakec9680921999-12-13 16:37:25 +00007980#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007981 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007982#endif
7983#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007984 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007985#endif
7986#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007987 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007988#endif
7989#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007990 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007991#endif
7992#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007993 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007994#endif
7995#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007996 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007997#endif
7998#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007999 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00008000#endif
8001#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008002 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008003#endif
8004#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008005 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008006#endif
Fred Draked86ed291999-12-15 15:34:33 +00008007#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008008 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008009#endif
8010#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008011 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008012#endif
Fred Drakec9680921999-12-13 16:37:25 +00008013#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008014 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008015#endif
8016#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008017 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008018#endif
8019#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008020 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008021#endif
8022#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008023 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008024#endif
8025#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008026 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008027#endif
8028#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008029 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008030#endif
8031#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008032 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008033#endif
8034#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008035 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008036#endif
8037#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008038 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008039#endif
8040#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008041 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008042#endif
8043#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008044 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008045#endif
8046#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008047 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008048#endif
8049#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008050 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008051#endif
8052#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008053 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008054#endif
8055#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008056 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008057#endif
8058#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008059 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008060#endif
8061#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008062 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008063#endif
8064#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008065 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008066#endif
8067#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008068 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008069#endif
8070#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008071 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008072#endif
8073#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008074 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008075#endif
8076#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008077 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008078#endif
8079#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008080 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008081#endif
8082#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008083 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008084#endif
8085#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008086 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008087#endif
8088#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008089 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008090#endif
8091#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008092 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008093#endif
8094#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008095 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008096#endif
8097#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008098 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008099#endif
8100#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008101 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008102#endif
8103#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008104 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008105#endif
8106#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008107 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008108#endif
8109#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008110 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008111#endif
8112#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008113 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008114#endif
8115#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008116 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008117#endif
Fred Draked86ed291999-12-15 15:34:33 +00008118#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008119 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008120#endif
Fred Drakec9680921999-12-13 16:37:25 +00008121#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008122 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008123#endif
8124#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008125 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008126#endif
8127#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008128 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008129#endif
8130#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008131 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008132#endif
8133#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008134 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008135#endif
8136#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008137 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008138#endif
8139#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008140 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008141#endif
8142#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008143 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008144#endif
8145#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008146 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008147#endif
8148#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008149 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008150#endif
8151#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008152 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008153#endif
8154#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008155 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008156#endif
8157#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008158 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008159#endif
8160#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008161 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008162#endif
8163#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008164 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008165#endif
8166#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008167 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008168#endif
8169#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008170 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008171#endif
8172#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008173 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008174#endif
8175#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008176 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008177#endif
8178#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008179 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008180#endif
8181#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008182 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008183#endif
8184#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008185 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008186#endif
8187#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008188 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008189#endif
8190#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008191 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008192#endif
8193#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008194 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008195#endif
8196#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008197 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008198#endif
8199#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008200 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008201#endif
8202#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008203 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008204#endif
8205#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008206 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008207#endif
8208#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008209 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008210#endif
8211#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008212 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008213#endif
8214#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008215 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008216#endif
8217#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008218 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008219#endif
8220#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008221 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008222#endif
8223#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008224 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008225#endif
8226#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008227 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008228#endif
8229#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008230 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008231#endif
8232#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008233 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008234#endif
8235#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008236 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008237#endif
8238#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008239 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008240#endif
8241#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008242 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008243#endif
8244#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008245 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008246#endif
8247#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008248 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008249#endif
8250#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008251 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008252#endif
8253#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008254 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008255#endif
8256};
8257
8258static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008259conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008260{
8261 return conv_confname(arg, valuep, posix_constants_sysconf,
8262 sizeof(posix_constants_sysconf)
8263 / sizeof(struct constdef));
8264}
8265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008266PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008267"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008268Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008269
8270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008271posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008272{
8273 PyObject *result = NULL;
8274 int name;
8275
8276 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008277 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008278
Victor Stinner862490a2010-05-06 00:03:44 +00008279 errno = 0;
8280 value = sysconf(name);
8281 if (value == -1 && errno != 0)
8282 posix_error();
8283 else
8284 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008285 }
8286 return result;
8287}
8288#endif
8289
8290
Fred Drakebec628d1999-12-15 18:31:10 +00008291/* This code is used to ensure that the tables of configuration value names
8292 * are in sorted order as required by conv_confname(), and also to build the
8293 * the exported dictionaries that are used to publish information about the
8294 * names available on the host platform.
8295 *
8296 * Sorting the table at runtime ensures that the table is properly ordered
8297 * when used, even for platforms we're not able to test on. It also makes
8298 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008299 */
Fred Drakebec628d1999-12-15 18:31:10 +00008300
8301static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008302cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008303{
8304 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008305 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008306 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008307 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008308
8309 return strcmp(c1->name, c2->name);
8310}
8311
8312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008313setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008314 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008315{
Fred Drakebec628d1999-12-15 18:31:10 +00008316 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008317 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008318
8319 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8320 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008321 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008322 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008323
Barry Warsaw3155db32000-04-13 15:20:40 +00008324 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008325 PyObject *o = PyInt_FromLong(table[i].value);
8326 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8327 Py_XDECREF(o);
8328 Py_DECREF(d);
8329 return -1;
8330 }
8331 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008332 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008333 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008334}
8335
Fred Drakebec628d1999-12-15 18:31:10 +00008336/* Return -1 on failure, 0 on success. */
8337static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008338setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008339{
8340#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008341 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008342 sizeof(posix_constants_pathconf)
8343 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008344 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008345 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008346#endif
8347#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008348 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008349 sizeof(posix_constants_confstr)
8350 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008351 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008352 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008353#endif
8354#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008355 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008356 sizeof(posix_constants_sysconf)
8357 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008358 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008359 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008360#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008361 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008362}
Fred Draked86ed291999-12-15 15:34:33 +00008363
8364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008365PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008366"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008367Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008368in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008369
8370static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008371posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008372{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008373 abort();
8374 /*NOTREACHED*/
8375 Py_FatalError("abort() called from Python code didn't abort!");
8376 return NULL;
8377}
Fred Drakebec628d1999-12-15 18:31:10 +00008378
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008379#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008380PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008381"startfile(filepath [, operation]) - Start a file with its associated\n\
8382application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008383\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008384When \"operation\" is not specified or \"open\", this acts like\n\
8385double-clicking the file in Explorer, or giving the file name as an\n\
8386argument to the DOS \"start\" command: the file is opened with whatever\n\
8387application (if any) its extension is associated.\n\
8388When another \"operation\" is given, it specifies what should be done with\n\
8389the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008390\n\
8391startfile returns as soon as the associated application is launched.\n\
8392There is no option to wait for the application to close, and no way\n\
8393to retrieve the application's exit status.\n\
8394\n\
8395The filepath is relative to the current directory. If you want to use\n\
8396an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008397the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008398
8399static PyObject *
8400win32_startfile(PyObject *self, PyObject *args)
8401{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008402 char *filepath;
8403 char *operation = NULL;
8404 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008405
Victor Stinnerd6f85422010-05-05 23:33:33 +00008406 PyObject *unipath, *woperation = NULL;
8407 if (!PyArg_ParseTuple(args, "U|s:startfile",
8408 &unipath, &operation)) {
8409 PyErr_Clear();
8410 goto normal;
8411 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008412
Victor Stinnerd6f85422010-05-05 23:33:33 +00008413 if (operation) {
8414 woperation = PyUnicode_DecodeASCII(operation,
8415 strlen(operation), NULL);
8416 if (!woperation) {
8417 PyErr_Clear();
8418 operation = NULL;
8419 goto normal;
8420 }
8421 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008422
Victor Stinnerd6f85422010-05-05 23:33:33 +00008423 Py_BEGIN_ALLOW_THREADS
8424 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8425 PyUnicode_AS_UNICODE(unipath),
8426 NULL, NULL, SW_SHOWNORMAL);
8427 Py_END_ALLOW_THREADS
8428
8429 Py_XDECREF(woperation);
8430 if (rc <= (HINSTANCE)32) {
8431 PyObject *errval = win32_error_unicode("startfile",
8432 PyUnicode_AS_UNICODE(unipath));
8433 return errval;
8434 }
8435 Py_INCREF(Py_None);
8436 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008437
8438normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008439 if (!PyArg_ParseTuple(args, "et|s:startfile",
8440 Py_FileSystemDefaultEncoding, &filepath,
8441 &operation))
8442 return NULL;
8443 Py_BEGIN_ALLOW_THREADS
8444 rc = ShellExecute((HWND)0, operation, filepath,
8445 NULL, NULL, SW_SHOWNORMAL);
8446 Py_END_ALLOW_THREADS
8447 if (rc <= (HINSTANCE)32) {
8448 PyObject *errval = win32_error("startfile", filepath);
8449 PyMem_Free(filepath);
8450 return errval;
8451 }
8452 PyMem_Free(filepath);
8453 Py_INCREF(Py_None);
8454 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008455}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008456#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008457
Martin v. Löwis438b5342002-12-27 10:16:42 +00008458#ifdef HAVE_GETLOADAVG
8459PyDoc_STRVAR(posix_getloadavg__doc__,
8460"getloadavg() -> (float, float, float)\n\n\
8461Return the number of processes in the system run queue averaged over\n\
8462the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8463was unobtainable");
8464
8465static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008466posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008467{
8468 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008469 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008470 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8471 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008472 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008473 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008474}
8475#endif
8476
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008477#ifdef MS_WINDOWS
8478
8479PyDoc_STRVAR(win32_urandom__doc__,
8480"urandom(n) -> str\n\n\
8481Return a string of n random bytes suitable for cryptographic use.");
8482
8483typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8484 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8485 DWORD dwFlags );
8486typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8487 BYTE *pbBuffer );
8488
8489static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008490/* This handle is never explicitly released. Instead, the operating
8491 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008492static HCRYPTPROV hCryptProv = 0;
8493
Tim Peters4ad82172004-08-30 17:02:04 +00008494static PyObject*
8495win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008496{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008497 int howMany;
8498 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008499
Victor Stinnerd6f85422010-05-05 23:33:33 +00008500 /* Read arguments */
8501 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8502 return NULL;
8503 if (howMany < 0)
8504 return PyErr_Format(PyExc_ValueError,
8505 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008506
Victor Stinnerd6f85422010-05-05 23:33:33 +00008507 if (hCryptProv == 0) {
8508 HINSTANCE hAdvAPI32 = NULL;
8509 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008510
Victor Stinnerd6f85422010-05-05 23:33:33 +00008511 /* Obtain handle to the DLL containing CryptoAPI
8512 This should not fail */
8513 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8514 if(hAdvAPI32 == NULL)
8515 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008516
Victor Stinnerd6f85422010-05-05 23:33:33 +00008517 /* Obtain pointers to the CryptoAPI functions
8518 This will fail on some early versions of Win95 */
8519 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8520 hAdvAPI32,
8521 "CryptAcquireContextA");
8522 if (pCryptAcquireContext == NULL)
8523 return PyErr_Format(PyExc_NotImplementedError,
8524 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008525
Victor Stinnerd6f85422010-05-05 23:33:33 +00008526 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8527 hAdvAPI32, "CryptGenRandom");
8528 if (pCryptGenRandom == NULL)
8529 return PyErr_Format(PyExc_NotImplementedError,
8530 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008531
Victor Stinnerd6f85422010-05-05 23:33:33 +00008532 /* Acquire context */
8533 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8534 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8535 return win32_error("CryptAcquireContext", NULL);
8536 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008537
Victor Stinnerd6f85422010-05-05 23:33:33 +00008538 /* Allocate bytes */
8539 result = PyString_FromStringAndSize(NULL, howMany);
8540 if (result != NULL) {
8541 /* Get random data */
8542 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8543 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8544 PyString_AS_STRING(result))) {
8545 Py_DECREF(result);
8546 return win32_error("CryptGenRandom", NULL);
8547 }
8548 }
8549 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008550}
8551#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008552
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008553#ifdef __VMS
8554/* Use openssl random routine */
8555#include <openssl/rand.h>
8556PyDoc_STRVAR(vms_urandom__doc__,
8557"urandom(n) -> str\n\n\
8558Return a string of n random bytes suitable for cryptographic use.");
8559
8560static PyObject*
8561vms_urandom(PyObject *self, PyObject *args)
8562{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008563 int howMany;
8564 PyObject* result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008565
Victor Stinnerd6f85422010-05-05 23:33:33 +00008566 /* Read arguments */
8567 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8568 return NULL;
8569 if (howMany < 0)
8570 return PyErr_Format(PyExc_ValueError,
8571 "negative argument not allowed");
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008572
Victor Stinnerd6f85422010-05-05 23:33:33 +00008573 /* Allocate bytes */
8574 result = PyString_FromStringAndSize(NULL, howMany);
8575 if (result != NULL) {
8576 /* Get random data */
8577 if (RAND_pseudo_bytes((unsigned char*)
8578 PyString_AS_STRING(result),
8579 howMany) < 0) {
8580 Py_DECREF(result);
8581 return PyErr_Format(PyExc_ValueError,
8582 "RAND_pseudo_bytes");
8583 }
8584 }
8585 return result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008586}
8587#endif
8588
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008589#ifdef HAVE_SETRESUID
8590PyDoc_STRVAR(posix_setresuid__doc__,
8591"setresuid(ruid, euid, suid)\n\n\
8592Set the current process's real, effective, and saved user ids.");
8593
8594static PyObject*
8595posix_setresuid (PyObject *self, PyObject *args)
8596{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008597 /* We assume uid_t is no larger than a long. */
8598 long ruid, euid, suid;
8599 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8600 return NULL;
8601 if (setresuid(ruid, euid, suid) < 0)
8602 return posix_error();
8603 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008604}
8605#endif
8606
8607#ifdef HAVE_SETRESGID
8608PyDoc_STRVAR(posix_setresgid__doc__,
8609"setresgid(rgid, egid, sgid)\n\n\
8610Set the current process's real, effective, and saved group ids.");
8611
8612static PyObject*
8613posix_setresgid (PyObject *self, PyObject *args)
8614{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008615 /* We assume uid_t is no larger than a long. */
8616 long rgid, egid, sgid;
8617 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8618 return NULL;
8619 if (setresgid(rgid, egid, sgid) < 0)
8620 return posix_error();
8621 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008622}
8623#endif
8624
8625#ifdef HAVE_GETRESUID
8626PyDoc_STRVAR(posix_getresuid__doc__,
8627"getresuid() -> (ruid, euid, suid)\n\n\
8628Get tuple of the current process's real, effective, and saved user ids.");
8629
8630static PyObject*
8631posix_getresuid (PyObject *self, PyObject *noargs)
8632{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008633 uid_t ruid, euid, suid;
8634 long l_ruid, l_euid, l_suid;
8635 if (getresuid(&ruid, &euid, &suid) < 0)
8636 return posix_error();
8637 /* Force the values into long's as we don't know the size of uid_t. */
8638 l_ruid = ruid;
8639 l_euid = euid;
8640 l_suid = suid;
8641 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008642}
8643#endif
8644
8645#ifdef HAVE_GETRESGID
8646PyDoc_STRVAR(posix_getresgid__doc__,
8647"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008648Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008649
8650static PyObject*
8651posix_getresgid (PyObject *self, PyObject *noargs)
8652{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008653 uid_t rgid, egid, sgid;
8654 long l_rgid, l_egid, l_sgid;
8655 if (getresgid(&rgid, &egid, &sgid) < 0)
8656 return posix_error();
8657 /* Force the values into long's as we don't know the size of uid_t. */
8658 l_rgid = rgid;
8659 l_egid = egid;
8660 l_sgid = sgid;
8661 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008662}
8663#endif
8664
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008665static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008666 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008667#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008668 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008669#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008670 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008671#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008672 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008673#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008674 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008675#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008676 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008677#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008678#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008679 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008680#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008681#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008682 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008683#endif /* HAVE_LCHMOD */
8684#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008685 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008686#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008687#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008688 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008689#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008690#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008691 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008692#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008693#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008694 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008695#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008696#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008697 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008698#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008699#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008700 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008701#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008702 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008703#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008704#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008705#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008706 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008707#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008708 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8709 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8710 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008711#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008712 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008713#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008714#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008715 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008716#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008717 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8718 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8719 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8720 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008721#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008722 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008723#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008724#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008725 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008726#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008727 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008728#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008729 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008730#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008731 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8732 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8733 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008734#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008735 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008736#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008737 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008738#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008739 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8740 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008741#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008742#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008743 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8744 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008745#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008746 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8747 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008748#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008749#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008750#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008751 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008752#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008753#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008754 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008755#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008756#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008757 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008758#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008759#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008760 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008761#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008762#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008763 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008764#endif /* HAVE_GETEGID */
8765#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008766 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008767#endif /* HAVE_GETEUID */
8768#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008769 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008770#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008771#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008772 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008773#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008774 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008775#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008776 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008777#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008778#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008779 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008780#endif /* HAVE_GETPPID */
8781#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008782 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008783#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008784#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008785 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008786#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008787#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008788 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008789#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008790#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008791 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008792#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008793#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008794 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008795#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008796#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008797 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008798#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008799 {"popen2", win32_popen2, METH_VARARGS},
8800 {"popen3", win32_popen3, METH_VARARGS},
8801 {"popen4", win32_popen4, METH_VARARGS},
8802 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8803 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008804#else
8805#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008806 {"popen2", os2emx_popen2, METH_VARARGS},
8807 {"popen3", os2emx_popen3, METH_VARARGS},
8808 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008809#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008810#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008811#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008812#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008813 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008814#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008815#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008816 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008817#endif /* HAVE_SETEUID */
8818#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008819 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008820#endif /* HAVE_SETEGID */
8821#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008822 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008823#endif /* HAVE_SETREUID */
8824#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008825 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008826#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008827#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008828 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008829#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008830#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008831 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008832#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008833#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008834 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008835#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008836#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008837 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008838#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008839#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008840 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008841#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008842#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008843 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008844#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008845#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008846 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008847#endif /* HAVE_WAIT3 */
8848#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008849 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008850#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008851#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008852 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008853#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008854#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008855 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008856#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008857#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008858 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008859#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008860#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008861 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008862#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008863#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008864 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008865#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008866#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008867 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008868#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008869 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8870 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8871 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8872 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8873 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8874 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8875 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8876 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8877 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8878 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8879 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008880#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008881 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008882#endif
8883#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008884 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008885#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008886#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008887 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008888#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008889#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008890 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8891 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8892 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008893#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008894#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008895 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008896#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008897#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008898 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008899#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008900#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008902#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008903 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008904#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008905 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008906#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008907#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008908 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008909#endif
8910#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008911 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008912#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008913#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008914#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008915 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008916#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008917#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008918 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008919#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008920#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008921 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008922#endif /* WIFSTOPPED */
8923#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008924 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008925#endif /* WIFSIGNALED */
8926#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008927 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008928#endif /* WIFEXITED */
8929#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008930 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008931#endif /* WEXITSTATUS */
8932#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008933 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008934#endif /* WTERMSIG */
8935#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008936 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008937#endif /* WSTOPSIG */
8938#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008939#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008940 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008941#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008942#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008943 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008944#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008945#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008946 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008947#endif
8948#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008949 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008950#endif
8951#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008952 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008953#endif
Fred Drakec9680921999-12-13 16:37:25 +00008954#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008955 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008956#endif
8957#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008958 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008959#endif
8960#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008961 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008962#endif
8963#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008964 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008965#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008966 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008967#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008968 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008969#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008970#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008971 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008972#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008973 #ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008974 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008975 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008976 #ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008977 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008978 #endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008979#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008980 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008981#endif
8982#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008983 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008984#endif
8985#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008986 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008987#endif
8988#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008989 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008990#endif
8991
Victor Stinnerd6f85422010-05-05 23:33:33 +00008992 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008993};
8994
8995
Barry Warsaw4a342091996-12-19 23:50:02 +00008996static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008997ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008998{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008999 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00009000}
9001
Guido van Rossumd48f2521997-12-05 22:19:34 +00009002#if defined(PYOS_OS2)
9003/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009004static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009005{
9006 APIRET rc;
9007 ULONG values[QSV_MAX+1];
9008 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009009 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009010
9011 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009012 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009013 Py_END_ALLOW_THREADS
9014
9015 if (rc != NO_ERROR) {
9016 os2_error(rc);
9017 return -1;
9018 }
9019
Fred Drake4d1e64b2002-04-15 19:40:07 +00009020 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9021 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9022 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9023 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9024 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9025 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9026 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009027
9028 switch (values[QSV_VERSION_MINOR]) {
9029 case 0: ver = "2.00"; break;
9030 case 10: ver = "2.10"; break;
9031 case 11: ver = "2.11"; break;
9032 case 30: ver = "3.00"; break;
9033 case 40: ver = "4.00"; break;
9034 case 50: ver = "5.00"; break;
9035 default:
Tim Peters885d4572001-11-28 20:27:42 +00009036 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009038 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009039 ver = &tmp[0];
9040 }
9041
9042 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009043 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009044 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009045
9046 /* Add Indicator of Which Drive was Used to Boot the System */
9047 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9048 tmp[1] = ':';
9049 tmp[2] = '\0';
9050
Fred Drake4d1e64b2002-04-15 19:40:07 +00009051 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009052}
9053#endif
9054
Barry Warsaw4a342091996-12-19 23:50:02 +00009055static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009056all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009057{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009058#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009059 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009060#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009061#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009062 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009063#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009064#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009065 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009066#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009067#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009068 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009069#endif
Fred Drakec9680921999-12-13 16:37:25 +00009070#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009071 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009072#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009073#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009074 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009075#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009076#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009077 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009078#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009079#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009080 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009081#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009082#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009083 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009084#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009085#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009086 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009087#endif
9088#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009090#endif
9091#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009092 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009093#endif
9094#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009095 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009096#endif
9097#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009098 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009099#endif
9100#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009101 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009102#endif
9103#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009104 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009105#endif
9106#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009107 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009108#endif
9109#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009110 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009111#endif
9112#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009113 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009114#endif
9115#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009117#endif
9118#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009119 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009120#endif
9121#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009122 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009123#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009124#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009125 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009126#endif
9127#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009128 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009129#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009130#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009131 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009132#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009133#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009134 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009135#endif
9136#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009137 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009138#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009139
Tim Peters5aa91602002-01-30 05:46:57 +00009140/* MS Windows */
9141#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009142 /* Don't inherit in child processes. */
9143 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009144#endif
9145#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009146 /* Optimize for short life (keep in memory). */
9147 /* MS forgot to define this one with a non-underscore form too. */
9148 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009149#endif
9150#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009151 /* Automatically delete when last handle is closed. */
9152 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009153#endif
9154#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009155 /* Optimize for random access. */
9156 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009157#endif
9158#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009159 /* Optimize for sequential access. */
9160 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009161#endif
9162
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009163/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009164#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009165 /* Send a SIGIO signal whenever input or output
9166 becomes available on file descriptor */
9167 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009168#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009169#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009170 /* Direct disk access. */
9171 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009172#endif
9173#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009174 /* Must be a directory. */
9175 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009176#endif
9177#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009178 /* Do not follow links. */
9179 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009180#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009181#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009182 /* Do not update the access time. */
9183 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009184#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009185
Victor Stinnerd6f85422010-05-05 23:33:33 +00009186 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009187#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009188 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009189#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009190#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009191 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009192#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009193#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009194 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009195#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009196#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009197 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009198#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009199#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009200 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009201#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009202#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009203 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009204#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009205#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009206 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009207#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009208#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009209 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009210#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009211#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009212 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009213#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009214#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009215 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009216#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009217#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009218 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009219#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009220#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009221 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009222#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009223#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009224 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009225#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009226#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009227 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009228#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009229#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009230 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009231#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009232#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009233 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009234#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009235#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009236 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009237#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009238
Guido van Rossum246bc171999-02-01 23:54:31 +00009239#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009240#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9242 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9243 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9244 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9245 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9246 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9247 if (ins(d, "P_PM", (long)P_PM)) return -1;
9248 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9249 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9250 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9251 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9252 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9253 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9254 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9255 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9256 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9257 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9258 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9259 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9260 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009261#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009262 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9263 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9264 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9265 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9266 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009267#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009268#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009269
Guido van Rossumd48f2521997-12-05 22:19:34 +00009270#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009271 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009272#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009273 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009274}
9275
9276
Tim Peters5aa91602002-01-30 05:46:57 +00009277#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009278#define INITFUNC initnt
9279#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009280
9281#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009282#define INITFUNC initos2
9283#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009284
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009285#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009286#define INITFUNC initposix
9287#define MODNAME "posix"
9288#endif
9289
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009290PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009291INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009292{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009293 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009294
Victor Stinnerd6f85422010-05-05 23:33:33 +00009295 m = Py_InitModule3(MODNAME,
9296 posix_methods,
9297 posix__doc__);
9298 if (m == NULL)
9299 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009300
Victor Stinnerd6f85422010-05-05 23:33:33 +00009301 /* Initialize environ dictionary */
9302 v = convertenviron();
9303 Py_XINCREF(v);
9304 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9305 return;
9306 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009307
Victor Stinnerd6f85422010-05-05 23:33:33 +00009308 if (all_ins(m))
9309 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009310
Victor Stinnerd6f85422010-05-05 23:33:33 +00009311 if (setup_confname_tables(m))
9312 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009313
Victor Stinnerd6f85422010-05-05 23:33:33 +00009314 Py_INCREF(PyExc_OSError);
9315 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009316
Guido van Rossumb3d39562000-01-31 18:41:26 +00009317#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009318 if (posix_putenv_garbage == NULL)
9319 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009320#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009321
Victor Stinnerd6f85422010-05-05 23:33:33 +00009322 if (!initialized) {
9323 stat_result_desc.name = MODNAME ".stat_result";
9324 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9325 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9326 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9327 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9328 structseq_new = StatResultType.tp_new;
9329 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009330
Victor Stinnerd6f85422010-05-05 23:33:33 +00009331 statvfs_result_desc.name = MODNAME ".statvfs_result";
9332 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009333#ifdef NEED_TICKS_PER_SECOND
9334# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009335 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009336# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009337 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009338# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009339 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009340# endif
9341#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009342 }
9343 Py_INCREF((PyObject*) &StatResultType);
9344 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9345 Py_INCREF((PyObject*) &StatVFSResultType);
9346 PyModule_AddObject(m, "statvfs_result",
9347 (PyObject*) &StatVFSResultType);
9348 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009349
9350#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009351 /*
9352 * Step 2 of weak-linking support on Mac OS X.
9353 *
9354 * The code below removes functions that are not available on the
9355 * currently active platform.
9356 *
9357 * This block allow one to use a python binary that was build on
9358 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9359 * OSX 10.4.
9360 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009361#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009362 if (fstatvfs == NULL) {
9363 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9364 return;
9365 }
9366 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009367#endif /* HAVE_FSTATVFS */
9368
9369#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009370 if (statvfs == NULL) {
9371 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9372 return;
9373 }
9374 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009375#endif /* HAVE_STATVFS */
9376
9377# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009378 if (lchown == NULL) {
9379 if (PyObject_DelAttrString(m, "lchown") == -1) {
9380 return;
9381 }
9382 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009383#endif /* HAVE_LCHOWN */
9384
9385
9386#endif /* __APPLE__ */
9387
Guido van Rossumb6775db1994-08-01 11:34:53 +00009388}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009389
9390#ifdef __cplusplus
9391}
9392#endif
9393
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009394