blob: bcc1219666ca808b55157e62a61693e1721b9bea [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);
2846 }
2847 Py_INCREF(Py_None);
2848 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002849done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002850 CloseHandle(hFile);
2851 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002852#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002853
Victor Stinnerd6f85422010-05-05 23:33:33 +00002854 char *path = NULL;
Amaury Forgeot d'Arcac514c82011-01-03 00:50:57 +00002855 time_t atime, mtime;
2856 long ausec, musec;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002857 int res;
2858 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002859
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002860#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002861 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002862#define ATIME buf[0].tv_sec
2863#define MTIME buf[1].tv_sec
2864#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002865/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002866 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002867#define ATIME buf.actime
2868#define MTIME buf.modtime
2869#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002870#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002871 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002872#define ATIME buf[0]
2873#define MTIME buf[1]
2874#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002875#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002876
Mark Hammond817c9292003-12-03 01:22:38 +00002877
Victor Stinnerd6f85422010-05-05 23:33:33 +00002878 if (!PyArg_ParseTuple(args, "etO:utime",
2879 Py_FileSystemDefaultEncoding, &path, &arg))
2880 return NULL;
2881 if (arg == Py_None) {
2882 /* optional time values not given */
2883 Py_BEGIN_ALLOW_THREADS
2884 res = utime(path, NULL);
2885 Py_END_ALLOW_THREADS
2886 }
2887 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2888 PyErr_SetString(PyExc_TypeError,
2889 "utime() arg 2 must be a tuple (atime, mtime)");
2890 PyMem_Free(path);
2891 return NULL;
2892 }
2893 else {
2894 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2895 &atime, &ausec) == -1) {
2896 PyMem_Free(path);
2897 return NULL;
2898 }
2899 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2900 &mtime, &musec) == -1) {
2901 PyMem_Free(path);
2902 return NULL;
2903 }
2904 ATIME = atime;
2905 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002906#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002907 buf[0].tv_usec = ausec;
2908 buf[1].tv_usec = musec;
2909 Py_BEGIN_ALLOW_THREADS
2910 res = utimes(path, buf);
2911 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002912#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002913 Py_BEGIN_ALLOW_THREADS
2914 res = utime(path, UTIME_ARG);
2915 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002916#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002917 }
2918 if (res < 0) {
2919 return posix_error_with_allocated_filename(path);
2920 }
2921 PyMem_Free(path);
2922 Py_INCREF(Py_None);
2923 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002924#undef UTIME_ARG
2925#undef ATIME
2926#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002927#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002928}
2929
Guido van Rossum85e3b011991-06-03 12:42:10 +00002930
Guido van Rossum3b066191991-06-04 19:40:25 +00002931/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002932
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002933PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002934"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002935Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002936
Barry Warsaw53699e91996-12-10 23:23:01 +00002937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002938posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002939{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002940 int sts;
2941 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2942 return NULL;
2943 _exit(sts);
2944 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002945}
2946
Martin v. Löwis114619e2002-10-07 06:44:21 +00002947#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2948static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002949free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002950{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002951 Py_ssize_t i;
2952 for (i = 0; i < count; i++)
2953 PyMem_Free(array[i]);
2954 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002955}
2956#endif
2957
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002959#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002960PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002961"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002962Execute an executable path with arguments, replacing current process.\n\
2963\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002964 path: path of executable file\n\
2965 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002966
Barry Warsaw53699e91996-12-10 23:23:01 +00002967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002968posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002969{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002970 char *path;
2971 PyObject *argv;
2972 char **argvlist;
2973 Py_ssize_t i, argc;
2974 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002975
Victor Stinnerd6f85422010-05-05 23:33:33 +00002976 /* execv has two arguments: (path, argv), where
2977 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002978
Victor Stinnerd6f85422010-05-05 23:33:33 +00002979 if (!PyArg_ParseTuple(args, "etO:execv",
2980 Py_FileSystemDefaultEncoding,
2981 &path, &argv))
2982 return NULL;
2983 if (PyList_Check(argv)) {
2984 argc = PyList_Size(argv);
2985 getitem = PyList_GetItem;
2986 }
2987 else if (PyTuple_Check(argv)) {
2988 argc = PyTuple_Size(argv);
2989 getitem = PyTuple_GetItem;
2990 }
2991 else {
2992 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2993 PyMem_Free(path);
2994 return NULL;
2995 }
2996 if (argc < 1) {
2997 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2998 PyMem_Free(path);
2999 return NULL;
3000 }
Guido van Rossum50422b42000-04-26 20:34:28 +00003001
Victor Stinnerd6f85422010-05-05 23:33:33 +00003002 argvlist = PyMem_NEW(char *, argc+1);
3003 if (argvlist == NULL) {
3004 PyMem_Free(path);
3005 return PyErr_NoMemory();
3006 }
3007 for (i = 0; i < argc; i++) {
3008 if (!PyArg_Parse((*getitem)(argv, i), "et",
3009 Py_FileSystemDefaultEncoding,
3010 &argvlist[i])) {
3011 free_string_array(argvlist, i);
3012 PyErr_SetString(PyExc_TypeError,
3013 "execv() arg 2 must contain only strings");
3014 PyMem_Free(path);
3015 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003016
Victor Stinnerd6f85422010-05-05 23:33:33 +00003017 }
3018 }
3019 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003020
Victor Stinnerd6f85422010-05-05 23:33:33 +00003021 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003022
Victor Stinnerd6f85422010-05-05 23:33:33 +00003023 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003024
Victor Stinnerd6f85422010-05-05 23:33:33 +00003025 free_string_array(argvlist, argc);
3026 PyMem_Free(path);
3027 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003028}
3029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003033Execute a path with arguments and environment, replacing current process.\n\
3034\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003035 path: path of executable file\n\
3036 args: tuple or list of arguments\n\
3037 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003038
Barry Warsaw53699e91996-12-10 23:23:01 +00003039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003040posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003041{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003042 char *path;
3043 PyObject *argv, *env;
3044 char **argvlist;
3045 char **envlist;
3046 PyObject *key, *val, *keys=NULL, *vals=NULL;
3047 Py_ssize_t i, pos, argc, envc;
3048 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3049 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003050
Victor Stinnerd6f85422010-05-05 23:33:33 +00003051 /* execve has three arguments: (path, argv, env), where
3052 argv is a list or tuple of strings and env is a dictionary
3053 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003054
Victor Stinnerd6f85422010-05-05 23:33:33 +00003055 if (!PyArg_ParseTuple(args, "etOO:execve",
3056 Py_FileSystemDefaultEncoding,
3057 &path, &argv, &env))
3058 return NULL;
3059 if (PyList_Check(argv)) {
3060 argc = PyList_Size(argv);
3061 getitem = PyList_GetItem;
3062 }
3063 else if (PyTuple_Check(argv)) {
3064 argc = PyTuple_Size(argv);
3065 getitem = PyTuple_GetItem;
3066 }
3067 else {
3068 PyErr_SetString(PyExc_TypeError,
3069 "execve() arg 2 must be a tuple or list");
3070 goto fail_0;
3071 }
3072 if (!PyMapping_Check(env)) {
3073 PyErr_SetString(PyExc_TypeError,
3074 "execve() arg 3 must be a mapping object");
3075 goto fail_0;
3076 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003077
Victor Stinnerd6f85422010-05-05 23:33:33 +00003078 argvlist = PyMem_NEW(char *, argc+1);
3079 if (argvlist == NULL) {
3080 PyErr_NoMemory();
3081 goto fail_0;
3082 }
3083 for (i = 0; i < argc; i++) {
3084 if (!PyArg_Parse((*getitem)(argv, i),
3085 "et;execve() arg 2 must contain only strings",
3086 Py_FileSystemDefaultEncoding,
3087 &argvlist[i]))
3088 {
3089 lastarg = i;
3090 goto fail_1;
3091 }
3092 }
3093 lastarg = argc;
3094 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003095
Victor Stinnerd6f85422010-05-05 23:33:33 +00003096 i = PyMapping_Size(env);
3097 if (i < 0)
3098 goto fail_1;
3099 envlist = PyMem_NEW(char *, i + 1);
3100 if (envlist == NULL) {
3101 PyErr_NoMemory();
3102 goto fail_1;
3103 }
3104 envc = 0;
3105 keys = PyMapping_Keys(env);
3106 vals = PyMapping_Values(env);
3107 if (!keys || !vals)
3108 goto fail_2;
3109 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3110 PyErr_SetString(PyExc_TypeError,
3111 "execve(): env.keys() or env.values() is not a list");
3112 goto fail_2;
3113 }
Tim Peters5aa91602002-01-30 05:46:57 +00003114
Victor Stinnerd6f85422010-05-05 23:33:33 +00003115 for (pos = 0; pos < i; pos++) {
3116 char *p, *k, *v;
3117 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003118
Victor Stinnerd6f85422010-05-05 23:33:33 +00003119 key = PyList_GetItem(keys, pos);
3120 val = PyList_GetItem(vals, pos);
3121 if (!key || !val)
3122 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003123
Victor Stinnerd6f85422010-05-05 23:33:33 +00003124 if (!PyArg_Parse(
3125 key,
3126 "s;execve() arg 3 contains a non-string key",
3127 &k) ||
3128 !PyArg_Parse(
3129 val,
3130 "s;execve() arg 3 contains a non-string value",
3131 &v))
3132 {
3133 goto fail_2;
3134 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003135
3136#if defined(PYOS_OS2)
3137 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3138 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3139#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003140 len = PyString_Size(key) + PyString_Size(val) + 2;
3141 p = PyMem_NEW(char, len);
3142 if (p == NULL) {
3143 PyErr_NoMemory();
3144 goto fail_2;
3145 }
3146 PyOS_snprintf(p, len, "%s=%s", k, v);
3147 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003148#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003149 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003150#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003151 }
3152 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153
Victor Stinnerd6f85422010-05-05 23:33:33 +00003154 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003155
Victor Stinnerd6f85422010-05-05 23:33:33 +00003156 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003157
Victor Stinnerd6f85422010-05-05 23:33:33 +00003158 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003159
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003160 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003161 while (--envc >= 0)
3162 PyMem_DEL(envlist[envc]);
3163 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003164 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003165 free_string_array(argvlist, lastarg);
3166 Py_XDECREF(vals);
3167 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003168 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003169 PyMem_Free(path);
3170 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003171}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003172#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003173
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003174
Guido van Rossuma1065681999-01-25 23:20:23 +00003175#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003178Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003179\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003180 mode: mode of process creation\n\
3181 path: path of executable file\n\
3182 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003183
3184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003185posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003186{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003187 char *path;
3188 PyObject *argv;
3189 char **argvlist;
3190 int mode, i;
3191 Py_ssize_t argc;
3192 Py_intptr_t spawnval;
3193 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003194
Victor Stinnerd6f85422010-05-05 23:33:33 +00003195 /* spawnv has three arguments: (mode, path, argv), where
3196 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003197
Victor Stinnerd6f85422010-05-05 23:33:33 +00003198 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3199 Py_FileSystemDefaultEncoding,
3200 &path, &argv))
3201 return NULL;
3202 if (PyList_Check(argv)) {
3203 argc = PyList_Size(argv);
3204 getitem = PyList_GetItem;
3205 }
3206 else if (PyTuple_Check(argv)) {
3207 argc = PyTuple_Size(argv);
3208 getitem = PyTuple_GetItem;
3209 }
3210 else {
3211 PyErr_SetString(PyExc_TypeError,
3212 "spawnv() arg 2 must be a tuple or list");
3213 PyMem_Free(path);
3214 return NULL;
3215 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003216
Victor Stinnerd6f85422010-05-05 23:33:33 +00003217 argvlist = PyMem_NEW(char *, argc+1);
3218 if (argvlist == NULL) {
3219 PyMem_Free(path);
3220 return PyErr_NoMemory();
3221 }
3222 for (i = 0; i < argc; i++) {
3223 if (!PyArg_Parse((*getitem)(argv, i), "et",
3224 Py_FileSystemDefaultEncoding,
3225 &argvlist[i])) {
3226 free_string_array(argvlist, i);
3227 PyErr_SetString(
3228 PyExc_TypeError,
3229 "spawnv() arg 2 must contain only strings");
3230 PyMem_Free(path);
3231 return NULL;
3232 }
3233 }
3234 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003235
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003236#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003237 Py_BEGIN_ALLOW_THREADS
3238 spawnval = spawnv(mode, path, argvlist);
3239 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003240#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003241 if (mode == _OLD_P_OVERLAY)
3242 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003243
Victor Stinnerd6f85422010-05-05 23:33:33 +00003244 Py_BEGIN_ALLOW_THREADS
3245 spawnval = _spawnv(mode, path, argvlist);
3246 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003247#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003248
Victor Stinnerd6f85422010-05-05 23:33:33 +00003249 free_string_array(argvlist, argc);
3250 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003251
Victor Stinnerd6f85422010-05-05 23:33:33 +00003252 if (spawnval == -1)
3253 return posix_error();
3254 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003255#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003256 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003257#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003258 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003259#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003260}
3261
3262
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003264"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003265Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003266\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003267 mode: mode of process creation\n\
3268 path: path of executable file\n\
3269 args: tuple or list of arguments\n\
3270 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003271
3272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003273posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003274{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003275 char *path;
3276 PyObject *argv, *env;
3277 char **argvlist;
3278 char **envlist;
3279 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3280 int mode, pos, envc;
3281 Py_ssize_t argc, i;
3282 Py_intptr_t spawnval;
3283 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3284 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003285
Victor Stinnerd6f85422010-05-05 23:33:33 +00003286 /* spawnve has four arguments: (mode, path, argv, env), where
3287 argv is a list or tuple of strings and env is a dictionary
3288 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003289
Victor Stinnerd6f85422010-05-05 23:33:33 +00003290 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3291 Py_FileSystemDefaultEncoding,
3292 &path, &argv, &env))
3293 return NULL;
3294 if (PyList_Check(argv)) {
3295 argc = PyList_Size(argv);
3296 getitem = PyList_GetItem;
3297 }
3298 else if (PyTuple_Check(argv)) {
3299 argc = PyTuple_Size(argv);
3300 getitem = PyTuple_GetItem;
3301 }
3302 else {
3303 PyErr_SetString(PyExc_TypeError,
3304 "spawnve() arg 2 must be a tuple or list");
3305 goto fail_0;
3306 }
3307 if (!PyMapping_Check(env)) {
3308 PyErr_SetString(PyExc_TypeError,
3309 "spawnve() arg 3 must be a mapping object");
3310 goto fail_0;
3311 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003312
Victor Stinnerd6f85422010-05-05 23:33:33 +00003313 argvlist = PyMem_NEW(char *, argc+1);
3314 if (argvlist == NULL) {
3315 PyErr_NoMemory();
3316 goto fail_0;
3317 }
3318 for (i = 0; i < argc; i++) {
3319 if (!PyArg_Parse((*getitem)(argv, i),
3320 "et;spawnve() arg 2 must contain only strings",
3321 Py_FileSystemDefaultEncoding,
3322 &argvlist[i]))
3323 {
3324 lastarg = i;
3325 goto fail_1;
3326 }
3327 }
3328 lastarg = argc;
3329 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003330
Victor Stinnerd6f85422010-05-05 23:33:33 +00003331 i = PyMapping_Size(env);
3332 if (i < 0)
3333 goto fail_1;
3334 envlist = PyMem_NEW(char *, i + 1);
3335 if (envlist == NULL) {
3336 PyErr_NoMemory();
3337 goto fail_1;
3338 }
3339 envc = 0;
3340 keys = PyMapping_Keys(env);
3341 vals = PyMapping_Values(env);
3342 if (!keys || !vals)
3343 goto fail_2;
3344 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3345 PyErr_SetString(PyExc_TypeError,
3346 "spawnve(): env.keys() or env.values() is not a list");
3347 goto fail_2;
3348 }
Tim Peters5aa91602002-01-30 05:46:57 +00003349
Victor Stinnerd6f85422010-05-05 23:33:33 +00003350 for (pos = 0; pos < i; pos++) {
3351 char *p, *k, *v;
3352 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003353
Victor Stinnerd6f85422010-05-05 23:33:33 +00003354 key = PyList_GetItem(keys, pos);
3355 val = PyList_GetItem(vals, pos);
3356 if (!key || !val)
3357 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003358
Victor Stinnerd6f85422010-05-05 23:33:33 +00003359 if (!PyArg_Parse(
3360 key,
3361 "s;spawnve() arg 3 contains a non-string key",
3362 &k) ||
3363 !PyArg_Parse(
3364 val,
3365 "s;spawnve() arg 3 contains a non-string value",
3366 &v))
3367 {
3368 goto fail_2;
3369 }
3370 len = PyString_Size(key) + PyString_Size(val) + 2;
3371 p = PyMem_NEW(char, len);
3372 if (p == NULL) {
3373 PyErr_NoMemory();
3374 goto fail_2;
3375 }
3376 PyOS_snprintf(p, len, "%s=%s", k, v);
3377 envlist[envc++] = p;
3378 }
3379 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003380
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003381#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003382 Py_BEGIN_ALLOW_THREADS
3383 spawnval = spawnve(mode, path, argvlist, envlist);
3384 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003385#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003386 if (mode == _OLD_P_OVERLAY)
3387 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003388
Victor Stinnerd6f85422010-05-05 23:33:33 +00003389 Py_BEGIN_ALLOW_THREADS
3390 spawnval = _spawnve(mode, path, argvlist, envlist);
3391 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003392#endif
Tim Peters25059d32001-12-07 20:35:43 +00003393
Victor Stinnerd6f85422010-05-05 23:33:33 +00003394 if (spawnval == -1)
3395 (void) posix_error();
3396 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003397#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003398 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003399#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003400 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003401#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003402
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003403 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003404 while (--envc >= 0)
3405 PyMem_DEL(envlist[envc]);
3406 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003407 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003408 free_string_array(argvlist, lastarg);
3409 Py_XDECREF(vals);
3410 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003411 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003412 PyMem_Free(path);
3413 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003414}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003415
3416/* OS/2 supports spawnvp & spawnvpe natively */
3417#if defined(PYOS_OS2)
3418PyDoc_STRVAR(posix_spawnvp__doc__,
3419"spawnvp(mode, file, args)\n\n\
3420Execute the program 'file' in a new process, using the environment\n\
3421search path to find the file.\n\
3422\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003423 mode: mode of process creation\n\
3424 file: executable file name\n\
3425 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003426
3427static PyObject *
3428posix_spawnvp(PyObject *self, PyObject *args)
3429{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003430 char *path;
3431 PyObject *argv;
3432 char **argvlist;
3433 int mode, i, argc;
3434 Py_intptr_t spawnval;
3435 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003436
Victor Stinnerd6f85422010-05-05 23:33:33 +00003437 /* spawnvp has three arguments: (mode, path, argv), where
3438 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003439
Victor Stinnerd6f85422010-05-05 23:33:33 +00003440 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3441 Py_FileSystemDefaultEncoding,
3442 &path, &argv))
3443 return NULL;
3444 if (PyList_Check(argv)) {
3445 argc = PyList_Size(argv);
3446 getitem = PyList_GetItem;
3447 }
3448 else if (PyTuple_Check(argv)) {
3449 argc = PyTuple_Size(argv);
3450 getitem = PyTuple_GetItem;
3451 }
3452 else {
3453 PyErr_SetString(PyExc_TypeError,
3454 "spawnvp() arg 2 must be a tuple or list");
3455 PyMem_Free(path);
3456 return NULL;
3457 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003458
Victor Stinnerd6f85422010-05-05 23:33:33 +00003459 argvlist = PyMem_NEW(char *, argc+1);
3460 if (argvlist == NULL) {
3461 PyMem_Free(path);
3462 return PyErr_NoMemory();
3463 }
3464 for (i = 0; i < argc; i++) {
3465 if (!PyArg_Parse((*getitem)(argv, i), "et",
3466 Py_FileSystemDefaultEncoding,
3467 &argvlist[i])) {
3468 free_string_array(argvlist, i);
3469 PyErr_SetString(
3470 PyExc_TypeError,
3471 "spawnvp() arg 2 must contain only strings");
3472 PyMem_Free(path);
3473 return NULL;
3474 }
3475 }
3476 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003477
Victor Stinnerd6f85422010-05-05 23:33:33 +00003478 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003479#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003480 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003481#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003482 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003483#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003484 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003485
Victor Stinnerd6f85422010-05-05 23:33:33 +00003486 free_string_array(argvlist, argc);
3487 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003488
Victor Stinnerd6f85422010-05-05 23:33:33 +00003489 if (spawnval == -1)
3490 return posix_error();
3491 else
3492 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003493}
3494
3495
3496PyDoc_STRVAR(posix_spawnvpe__doc__,
3497"spawnvpe(mode, file, args, env)\n\n\
3498Execute the program 'file' in a new process, using the environment\n\
3499search path to find the file.\n\
3500\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003501 mode: mode of process creation\n\
3502 file: executable file name\n\
3503 args: tuple or list of arguments\n\
3504 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003505
3506static PyObject *
3507posix_spawnvpe(PyObject *self, PyObject *args)
3508{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003509 char *path;
3510 PyObject *argv, *env;
3511 char **argvlist;
3512 char **envlist;
3513 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3514 int mode, i, pos, argc, envc;
3515 Py_intptr_t spawnval;
3516 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3517 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003518
Victor Stinnerd6f85422010-05-05 23:33:33 +00003519 /* spawnvpe has four arguments: (mode, path, argv, env), where
3520 argv is a list or tuple of strings and env is a dictionary
3521 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003522
Victor Stinnerd6f85422010-05-05 23:33:33 +00003523 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3524 Py_FileSystemDefaultEncoding,
3525 &path, &argv, &env))
3526 return NULL;
3527 if (PyList_Check(argv)) {
3528 argc = PyList_Size(argv);
3529 getitem = PyList_GetItem;
3530 }
3531 else if (PyTuple_Check(argv)) {
3532 argc = PyTuple_Size(argv);
3533 getitem = PyTuple_GetItem;
3534 }
3535 else {
3536 PyErr_SetString(PyExc_TypeError,
3537 "spawnvpe() arg 2 must be a tuple or list");
3538 goto fail_0;
3539 }
3540 if (!PyMapping_Check(env)) {
3541 PyErr_SetString(PyExc_TypeError,
3542 "spawnvpe() arg 3 must be a mapping object");
3543 goto fail_0;
3544 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003545
Victor Stinnerd6f85422010-05-05 23:33:33 +00003546 argvlist = PyMem_NEW(char *, argc+1);
3547 if (argvlist == NULL) {
3548 PyErr_NoMemory();
3549 goto fail_0;
3550 }
3551 for (i = 0; i < argc; i++) {
3552 if (!PyArg_Parse((*getitem)(argv, i),
3553 "et;spawnvpe() arg 2 must contain only strings",
3554 Py_FileSystemDefaultEncoding,
3555 &argvlist[i]))
3556 {
3557 lastarg = i;
3558 goto fail_1;
3559 }
3560 }
3561 lastarg = argc;
3562 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003563
Victor Stinnerd6f85422010-05-05 23:33:33 +00003564 i = PyMapping_Size(env);
3565 if (i < 0)
3566 goto fail_1;
3567 envlist = PyMem_NEW(char *, i + 1);
3568 if (envlist == NULL) {
3569 PyErr_NoMemory();
3570 goto fail_1;
3571 }
3572 envc = 0;
3573 keys = PyMapping_Keys(env);
3574 vals = PyMapping_Values(env);
3575 if (!keys || !vals)
3576 goto fail_2;
3577 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3578 PyErr_SetString(PyExc_TypeError,
3579 "spawnvpe(): env.keys() or env.values() is not a list");
3580 goto fail_2;
3581 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003582
Victor Stinnerd6f85422010-05-05 23:33:33 +00003583 for (pos = 0; pos < i; pos++) {
3584 char *p, *k, *v;
3585 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003586
Victor Stinnerd6f85422010-05-05 23:33:33 +00003587 key = PyList_GetItem(keys, pos);
3588 val = PyList_GetItem(vals, pos);
3589 if (!key || !val)
3590 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003591
Victor Stinnerd6f85422010-05-05 23:33:33 +00003592 if (!PyArg_Parse(
3593 key,
3594 "s;spawnvpe() arg 3 contains a non-string key",
3595 &k) ||
3596 !PyArg_Parse(
3597 val,
3598 "s;spawnvpe() arg 3 contains a non-string value",
3599 &v))
3600 {
3601 goto fail_2;
3602 }
3603 len = PyString_Size(key) + PyString_Size(val) + 2;
3604 p = PyMem_NEW(char, len);
3605 if (p == NULL) {
3606 PyErr_NoMemory();
3607 goto fail_2;
3608 }
3609 PyOS_snprintf(p, len, "%s=%s", k, v);
3610 envlist[envc++] = p;
3611 }
3612 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003613
Victor Stinnerd6f85422010-05-05 23:33:33 +00003614 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003615#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003616 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003617#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003618 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003619#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003620 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003621
Victor Stinnerd6f85422010-05-05 23:33:33 +00003622 if (spawnval == -1)
3623 (void) posix_error();
3624 else
3625 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003626
3627 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003628 while (--envc >= 0)
3629 PyMem_DEL(envlist[envc]);
3630 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003631 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003632 free_string_array(argvlist, lastarg);
3633 Py_XDECREF(vals);
3634 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003635 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003636 PyMem_Free(path);
3637 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003638}
3639#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003640#endif /* HAVE_SPAWNV */
3641
3642
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003643#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003644PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003645"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003646Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3647\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003648Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003649
3650static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003651posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003652{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003653 pid_t pid;
3654 int result = 0;
3655 _PyImport_AcquireLock();
3656 pid = fork1();
3657 if (pid == 0) {
3658 /* child: this clobbers and resets the import lock. */
3659 PyOS_AfterFork();
3660 } else {
3661 /* parent: release the import lock. */
3662 result = _PyImport_ReleaseLock();
3663 }
3664 if (pid == -1)
3665 return posix_error();
3666 if (result < 0) {
3667 /* Don't clobber the OSError if the fork failed. */
3668 PyErr_SetString(PyExc_RuntimeError,
3669 "not holding the import lock");
3670 return NULL;
3671 }
3672 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003673}
3674#endif
3675
3676
Guido van Rossumad0ee831995-03-01 10:34:45 +00003677#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003678PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003679"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003680Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003681Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003682
Barry Warsaw53699e91996-12-10 23:23:01 +00003683static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003684posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003685{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003686 pid_t pid;
3687 int result = 0;
3688 _PyImport_AcquireLock();
3689 pid = fork();
3690 if (pid == 0) {
3691 /* child: this clobbers and resets the import lock. */
3692 PyOS_AfterFork();
3693 } else {
3694 /* parent: release the import lock. */
3695 result = _PyImport_ReleaseLock();
3696 }
3697 if (pid == -1)
3698 return posix_error();
3699 if (result < 0) {
3700 /* Don't clobber the OSError if the fork failed. */
3701 PyErr_SetString(PyExc_RuntimeError,
3702 "not holding the import lock");
3703 return NULL;
3704 }
3705 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003706}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003707#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003708
Neal Norwitzb59798b2003-03-21 01:43:31 +00003709/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003710/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3711#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003712#define DEV_PTY_FILE "/dev/ptc"
3713#define HAVE_DEV_PTMX
3714#else
3715#define DEV_PTY_FILE "/dev/ptmx"
3716#endif
3717
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003718#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003719#ifdef HAVE_PTY_H
3720#include <pty.h>
3721#else
3722#ifdef HAVE_LIBUTIL_H
3723#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003724#else
3725#ifdef HAVE_UTIL_H
3726#include <util.h>
3727#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003728#endif /* HAVE_LIBUTIL_H */
3729#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003730#ifdef HAVE_STROPTS_H
3731#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003732#endif
3733#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003734
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003735#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003736PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003737"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003738Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003739
3740static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003741posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003742{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003743 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003744#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003745 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003746#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003747#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003748 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003749#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003750 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003751#endif
3752#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003753
Thomas Wouters70c21a12000-07-14 14:28:33 +00003754#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003755 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3756 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003757#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003758 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3759 if (slave_name == NULL)
3760 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003761
Victor Stinnerd6f85422010-05-05 23:33:33 +00003762 slave_fd = open(slave_name, O_RDWR);
3763 if (slave_fd < 0)
3764 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003765#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003766 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3767 if (master_fd < 0)
3768 return posix_error();
3769 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3770 /* change permission of slave */
3771 if (grantpt(master_fd) < 0) {
3772 PyOS_setsig(SIGCHLD, sig_saved);
3773 return posix_error();
3774 }
3775 /* unlock slave */
3776 if (unlockpt(master_fd) < 0) {
3777 PyOS_setsig(SIGCHLD, sig_saved);
3778 return posix_error();
3779 }
3780 PyOS_setsig(SIGCHLD, sig_saved);
3781 slave_name = ptsname(master_fd); /* get name of slave */
3782 if (slave_name == NULL)
3783 return posix_error();
3784 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3785 if (slave_fd < 0)
3786 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003787#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003788 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3789 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003790#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003791 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003792#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003793#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003794#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003795
Victor Stinnerd6f85422010-05-05 23:33:33 +00003796 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003797
Fred Drake8cef4cf2000-06-28 16:40:38 +00003798}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003799#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003800
3801#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003802PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003803"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003804Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3805Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003806To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003807
3808static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003809posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003810{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003811 int master_fd = -1, result = 0;
3812 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003813
Victor Stinnerd6f85422010-05-05 23:33:33 +00003814 _PyImport_AcquireLock();
3815 pid = forkpty(&master_fd, NULL, NULL, NULL);
3816 if (pid == 0) {
3817 /* child: this clobbers and resets the import lock. */
3818 PyOS_AfterFork();
3819 } else {
3820 /* parent: release the import lock. */
3821 result = _PyImport_ReleaseLock();
3822 }
3823 if (pid == -1)
3824 return posix_error();
3825 if (result < 0) {
3826 /* Don't clobber the OSError if the fork failed. */
3827 PyErr_SetString(PyExc_RuntimeError,
3828 "not holding the import lock");
3829 return NULL;
3830 }
3831 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003832}
3833#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003834
Guido van Rossumad0ee831995-03-01 10:34:45 +00003835#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003836PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003837"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003838Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003839
Barry Warsaw53699e91996-12-10 23:23:01 +00003840static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003841posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003842{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003843 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003844}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003845#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003846
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003847
Guido van Rossumad0ee831995-03-01 10:34:45 +00003848#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003849PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003850"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003851Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003852
Barry Warsaw53699e91996-12-10 23:23:01 +00003853static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003854posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003855{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003856 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003857}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003858#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003860
Guido van Rossumad0ee831995-03-01 10:34:45 +00003861#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003862PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003863"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003864Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003865
Barry Warsaw53699e91996-12-10 23:23:01 +00003866static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003867posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003868{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003869 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003870}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003871#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003874PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003875"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003876Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003877
Barry Warsaw53699e91996-12-10 23:23:01 +00003878static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003879posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003880{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003881 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003882}
3883
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003884
Fred Drakec9680921999-12-13 16:37:25 +00003885#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003886PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003887"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003888Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003889
3890static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003891posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003892{
3893 PyObject *result = NULL;
3894
Fred Drakec9680921999-12-13 16:37:25 +00003895#ifdef NGROUPS_MAX
3896#define MAX_GROUPS NGROUPS_MAX
3897#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003898 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003899#define MAX_GROUPS 64
3900#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003901 gid_t grouplist[MAX_GROUPS];
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003902
3903 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
3904 * This is a helper variable to store the intermediate result when
3905 * that happens.
3906 *
3907 * To keep the code readable the OSX behaviour is unconditional,
3908 * according to the POSIX spec this should be safe on all unix-y
3909 * systems.
3910 */
3911 gid_t* alt_grouplist = grouplist;
Victor Stinnerd6f85422010-05-05 23:33:33 +00003912 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003913
Victor Stinnerd6f85422010-05-05 23:33:33 +00003914 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003915 if (n < 0) {
3916 if (errno == EINVAL) {
3917 n = getgroups(0, NULL);
3918 if (n == -1) {
3919 return posix_error();
3920 }
3921 if (n == 0) {
3922 /* Avoid malloc(0) */
3923 alt_grouplist = grouplist;
3924 } else {
3925 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
3926 if (alt_grouplist == NULL) {
3927 errno = EINVAL;
3928 return posix_error();
3929 }
3930 n = getgroups(n, alt_grouplist);
3931 if (n == -1) {
3932 PyMem_Free(alt_grouplist);
3933 return posix_error();
3934 }
3935 }
3936 } else {
3937 return posix_error();
3938 }
3939 }
3940 result = PyList_New(n);
3941 if (result != NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00003942 int i;
3943 for (i = 0; i < n; ++i) {
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003944 PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003945 if (o == NULL) {
Stefan Krah93f7a322010-11-26 17:35:50 +00003946 Py_DECREF(result);
3947 result = NULL;
3948 break;
Fred Drakec9680921999-12-13 16:37:25 +00003949 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003950 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003951 }
Ronald Oussoren9e7ffae2010-07-24 09:46:41 +00003952 }
3953
3954 if (alt_grouplist != grouplist) {
3955 PyMem_Free(alt_grouplist);
Victor Stinnerd6f85422010-05-05 23:33:33 +00003956 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003957
Fred Drakec9680921999-12-13 16:37:25 +00003958 return result;
3959}
3960#endif
3961
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003962#ifdef HAVE_INITGROUPS
3963PyDoc_STRVAR(posix_initgroups__doc__,
3964"initgroups(username, gid) -> None\n\n\
3965Call the system initgroups() to initialize the group access list with all of\n\
3966the groups of which the specified username is a member, plus the specified\n\
3967group id.");
3968
3969static PyObject *
3970posix_initgroups(PyObject *self, PyObject *args)
3971{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003972 char *username;
3973 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003974
Victor Stinnerd6f85422010-05-05 23:33:33 +00003975 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3976 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003977
Victor Stinnerd6f85422010-05-05 23:33:33 +00003978 if (initgroups(username, (gid_t) gid) == -1)
3979 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003980
Victor Stinnerd6f85422010-05-05 23:33:33 +00003981 Py_INCREF(Py_None);
3982 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003983}
3984#endif
3985
Martin v. Löwis606edc12002-06-13 21:09:11 +00003986#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003987PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003988"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003989Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003990
3991static PyObject *
3992posix_getpgid(PyObject *self, PyObject *args)
3993{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003994 pid_t pid, pgid;
3995 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3996 return NULL;
3997 pgid = getpgid(pid);
3998 if (pgid < 0)
3999 return posix_error();
4000 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00004001}
4002#endif /* HAVE_GETPGID */
4003
4004
Guido van Rossumb6775db1994-08-01 11:34:53 +00004005#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004006PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004007"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004009
Barry Warsaw53699e91996-12-10 23:23:01 +00004010static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004011posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00004012{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004013#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004014 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004015#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004016 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004017#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00004018}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004019#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00004020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004021
Guido van Rossumb6775db1994-08-01 11:34:53 +00004022#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004023PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004024"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00004025Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004026
Barry Warsaw53699e91996-12-10 23:23:01 +00004027static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004028posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004029{
Guido van Rossum64933891994-10-20 21:56:42 +00004030#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00004031 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004032#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004033 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00004034#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00004035 return posix_error();
4036 Py_INCREF(Py_None);
4037 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004038}
4039
Guido van Rossumb6775db1994-08-01 11:34:53 +00004040#endif /* HAVE_SETPGRP */
4041
Guido van Rossumad0ee831995-03-01 10:34:45 +00004042#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004043PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004044"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004046
Barry Warsaw53699e91996-12-10 23:23:01 +00004047static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004048posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004049{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004050 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00004051}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004052#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004054
Fred Drake12c6e2d1999-12-14 21:25:03 +00004055#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004056PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004057"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004058Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004059
4060static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004061posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004062{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004063 PyObject *result = NULL;
4064 char *name;
4065 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004066
Victor Stinnerd6f85422010-05-05 23:33:33 +00004067 errno = 0;
4068 name = getlogin();
4069 if (name == NULL) {
4070 if (errno)
4071 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004072 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004073 PyErr_SetString(PyExc_OSError,
4074 "unable to determine login name");
4075 }
4076 else
4077 result = PyString_FromString(name);
4078 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004079
Fred Drake12c6e2d1999-12-14 21:25:03 +00004080 return result;
4081}
4082#endif
4083
Guido van Rossumad0ee831995-03-01 10:34:45 +00004084#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004086"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004087Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004088
Barry Warsaw53699e91996-12-10 23:23:01 +00004089static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004090posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004091{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004092 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004093}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004094#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004096
Guido van Rossumad0ee831995-03-01 10:34:45 +00004097#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004098PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004099"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004100Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004101
Barry Warsaw53699e91996-12-10 23:23:01 +00004102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004103posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004104{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004105 pid_t pid;
4106 int sig;
4107 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4108 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004109#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004110 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4111 APIRET rc;
4112 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004113 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004114
4115 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4116 APIRET rc;
4117 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004118 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004119
4120 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004121 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004122#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004123 if (kill(pid, sig) == -1)
4124 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004125#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004126 Py_INCREF(Py_None);
4127 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004128}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004129#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004130
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004131#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004132PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004133"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004134Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004135
4136static PyObject *
4137posix_killpg(PyObject *self, PyObject *args)
4138{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004139 int sig;
4140 pid_t pgid;
4141 /* XXX some man pages make the `pgid` parameter an int, others
4142 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4143 take the same type. Moreover, pid_t is always at least as wide as
4144 int (else compilation of this module fails), which is safe. */
4145 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4146 return NULL;
4147 if (killpg(pgid, sig) == -1)
4148 return posix_error();
4149 Py_INCREF(Py_None);
4150 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004151}
4152#endif
4153
Brian Curtine5aa8862010-04-02 23:26:06 +00004154#ifdef MS_WINDOWS
4155PyDoc_STRVAR(win32_kill__doc__,
4156"kill(pid, sig)\n\n\
4157Kill a process with a signal.");
4158
4159static PyObject *
4160win32_kill(PyObject *self, PyObject *args)
4161{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004162 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004163 DWORD pid, sig, err;
4164 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004165
Victor Stinnerd6f85422010-05-05 23:33:33 +00004166 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4167 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004168
Victor Stinnerd6f85422010-05-05 23:33:33 +00004169 /* Console processes which share a common console can be sent CTRL+C or
4170 CTRL+BREAK events, provided they handle said events. */
4171 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4172 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4173 err = GetLastError();
4174 return PyErr_SetFromWindowsErr(err);
4175 }
4176 else
4177 Py_RETURN_NONE;
4178 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004179
Victor Stinnerd6f85422010-05-05 23:33:33 +00004180 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4181 attempt to open and terminate the process. */
4182 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4183 if (handle == NULL) {
4184 err = GetLastError();
4185 return PyErr_SetFromWindowsErr(err);
4186 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004187
Victor Stinnerd6f85422010-05-05 23:33:33 +00004188 if (TerminateProcess(handle, sig) == 0) {
4189 err = GetLastError();
4190 result = PyErr_SetFromWindowsErr(err);
4191 } else {
4192 Py_INCREF(Py_None);
4193 result = Py_None;
4194 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004195
Victor Stinnerd6f85422010-05-05 23:33:33 +00004196 CloseHandle(handle);
4197 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004198}
4199#endif /* MS_WINDOWS */
4200
Guido van Rossumc0125471996-06-28 18:55:32 +00004201#ifdef HAVE_PLOCK
4202
4203#ifdef HAVE_SYS_LOCK_H
4204#include <sys/lock.h>
4205#endif
4206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004207PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004208"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004209Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004210
Barry Warsaw53699e91996-12-10 23:23:01 +00004211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004212posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004213{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004214 int op;
4215 if (!PyArg_ParseTuple(args, "i:plock", &op))
4216 return NULL;
4217 if (plock(op) == -1)
4218 return posix_error();
4219 Py_INCREF(Py_None);
4220 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004221}
4222#endif
4223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004224
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004225#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004228Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004229
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004230#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004231#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004232static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004233async_system(const char *command)
4234{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004235 char errormsg[256], args[1024];
4236 RESULTCODES rcodes;
4237 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004238
Victor Stinnerd6f85422010-05-05 23:33:33 +00004239 char *shell = getenv("COMSPEC");
4240 if (!shell)
4241 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004242
Victor Stinnerd6f85422010-05-05 23:33:33 +00004243 /* avoid overflowing the argument buffer */
4244 if (strlen(shell) + 3 + strlen(command) >= 1024)
4245 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004246
Victor Stinnerd6f85422010-05-05 23:33:33 +00004247 args[0] = '\0';
4248 strcat(args, shell);
4249 strcat(args, "/c ");
4250 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004251
Victor Stinnerd6f85422010-05-05 23:33:33 +00004252 /* execute asynchronously, inheriting the environment */
4253 rc = DosExecPgm(errormsg,
4254 sizeof(errormsg),
4255 EXEC_ASYNC,
4256 args,
4257 NULL,
4258 &rcodes,
4259 shell);
4260 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004261}
4262
Guido van Rossumd48f2521997-12-05 22:19:34 +00004263static FILE *
4264popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004265{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004266 int oldfd, tgtfd;
4267 HFILE pipeh[2];
4268 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004269
Victor Stinnerd6f85422010-05-05 23:33:33 +00004270 /* mode determines which of stdin or stdout is reconnected to
4271 * the pipe to the child
4272 */
4273 if (strchr(mode, 'r') != NULL) {
4274 tgt_fd = 1; /* stdout */
4275 } else if (strchr(mode, 'w')) {
4276 tgt_fd = 0; /* stdin */
4277 } else {
4278 *err = ERROR_INVALID_ACCESS;
4279 return NULL;
4280 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004281
Victor Stinnerd6f85422010-05-05 23:33:33 +00004282 /* setup the pipe */
4283 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4284 *err = rc;
4285 return NULL;
4286 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004287
Victor Stinnerd6f85422010-05-05 23:33:33 +00004288 /* prevent other threads accessing stdio */
4289 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004290
Victor Stinnerd6f85422010-05-05 23:33:33 +00004291 /* reconnect stdio and execute child */
4292 oldfd = dup(tgtfd);
4293 close(tgtfd);
4294 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4295 DosClose(pipeh[tgtfd]);
4296 rc = async_system(command);
4297 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004298
Victor Stinnerd6f85422010-05-05 23:33:33 +00004299 /* restore stdio */
4300 dup2(oldfd, tgtfd);
4301 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004302
Victor Stinnerd6f85422010-05-05 23:33:33 +00004303 /* allow other threads access to stdio */
4304 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004305
Victor Stinnerd6f85422010-05-05 23:33:33 +00004306 /* if execution of child was successful return file stream */
4307 if (rc == NO_ERROR)
4308 return fdopen(pipeh[1 - tgtfd], mode);
4309 else {
4310 DosClose(pipeh[1 - tgtfd]);
4311 *err = rc;
4312 return NULL;
4313 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004314}
4315
4316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004317posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004318{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004319 char *name;
4320 char *mode = "r";
4321 int err, bufsize = -1;
4322 FILE *fp;
4323 PyObject *f;
4324 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4325 return NULL;
4326 Py_BEGIN_ALLOW_THREADS
4327 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4328 Py_END_ALLOW_THREADS
4329 if (fp == NULL)
4330 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004331
Victor Stinnerd6f85422010-05-05 23:33:33 +00004332 f = PyFile_FromFile(fp, name, mode, fclose);
4333 if (f != NULL)
4334 PyFile_SetBufSize(f, bufsize);
4335 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004336}
4337
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004338#elif defined(PYCC_GCC)
4339
4340/* standard posix version of popen() support */
4341static PyObject *
4342posix_popen(PyObject *self, PyObject *args)
4343{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004344 char *name;
4345 char *mode = "r";
4346 int bufsize = -1;
4347 FILE *fp;
4348 PyObject *f;
4349 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4350 return NULL;
4351 Py_BEGIN_ALLOW_THREADS
4352 fp = popen(name, mode);
4353 Py_END_ALLOW_THREADS
4354 if (fp == NULL)
4355 return posix_error();
4356 f = PyFile_FromFile(fp, name, mode, pclose);
4357 if (f != NULL)
4358 PyFile_SetBufSize(f, bufsize);
4359 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004360}
4361
4362/* fork() under OS/2 has lots'o'warts
4363 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4364 * most of this code is a ripoff of the win32 code, but using the
4365 * capabilities of EMX's C library routines
4366 */
4367
4368/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4369#define POPEN_1 1
4370#define POPEN_2 2
4371#define POPEN_3 3
4372#define POPEN_4 4
4373
4374static PyObject *_PyPopen(char *, int, int, int);
4375static int _PyPclose(FILE *file);
4376
4377/*
4378 * Internal dictionary mapping popen* file pointers to process handles,
4379 * for use when retrieving the process exit code. See _PyPclose() below
4380 * for more information on this dictionary's use.
4381 */
4382static PyObject *_PyPopenProcs = NULL;
4383
4384/* os2emx version of popen2()
4385 *
4386 * The result of this function is a pipe (file) connected to the
4387 * process's stdin, and a pipe connected to the process's stdout.
4388 */
4389
4390static PyObject *
4391os2emx_popen2(PyObject *self, PyObject *args)
4392{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004393 PyObject *f;
4394 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004395
Victor Stinnerd6f85422010-05-05 23:33:33 +00004396 char *cmdstring;
4397 char *mode = "t";
4398 int bufsize = -1;
4399 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4400 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004401
Victor Stinnerd6f85422010-05-05 23:33:33 +00004402 if (*mode == 't')
4403 tm = O_TEXT;
4404 else if (*mode != 'b') {
4405 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4406 return NULL;
4407 } else
4408 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004409
Victor Stinnerd6f85422010-05-05 23:33:33 +00004410 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004411
Victor Stinnerd6f85422010-05-05 23:33:33 +00004412 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004413}
4414
4415/*
4416 * Variation on os2emx.popen2
4417 *
4418 * The result of this function is 3 pipes - the process's stdin,
4419 * stdout and stderr
4420 */
4421
4422static PyObject *
4423os2emx_popen3(PyObject *self, PyObject *args)
4424{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004425 PyObject *f;
4426 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004427
Victor Stinnerd6f85422010-05-05 23:33:33 +00004428 char *cmdstring;
4429 char *mode = "t";
4430 int bufsize = -1;
4431 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4432 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004433
Victor Stinnerd6f85422010-05-05 23:33:33 +00004434 if (*mode == 't')
4435 tm = O_TEXT;
4436 else if (*mode != 'b') {
4437 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4438 return NULL;
4439 } else
4440 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004441
Victor Stinnerd6f85422010-05-05 23:33:33 +00004442 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004443
Victor Stinnerd6f85422010-05-05 23:33:33 +00004444 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004445}
4446
4447/*
4448 * Variation on os2emx.popen2
4449 *
Tim Peters11b23062003-04-23 02:39:17 +00004450 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004451 * and stdout+stderr combined as a single pipe.
4452 */
4453
4454static PyObject *
4455os2emx_popen4(PyObject *self, PyObject *args)
4456{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004457 PyObject *f;
4458 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004459
Victor Stinnerd6f85422010-05-05 23:33:33 +00004460 char *cmdstring;
4461 char *mode = "t";
4462 int bufsize = -1;
4463 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4464 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004465
Victor Stinnerd6f85422010-05-05 23:33:33 +00004466 if (*mode == 't')
4467 tm = O_TEXT;
4468 else if (*mode != 'b') {
4469 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4470 return NULL;
4471 } else
4472 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004473
Victor Stinnerd6f85422010-05-05 23:33:33 +00004474 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004475
Victor Stinnerd6f85422010-05-05 23:33:33 +00004476 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004477}
4478
4479/* a couple of structures for convenient handling of multiple
4480 * file handles and pipes
4481 */
4482struct file_ref
4483{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004484 int handle;
4485 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004486};
4487
4488struct pipe_ref
4489{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004490 int rd;
4491 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004492};
4493
4494/* The following code is derived from the win32 code */
4495
4496static PyObject *
4497_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4498{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004499 struct file_ref stdio[3];
4500 struct pipe_ref p_fd[3];
4501 FILE *p_s[3];
4502 int file_count, i, pipe_err;
4503 pid_t pipe_pid;
4504 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4505 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004506
Victor Stinnerd6f85422010-05-05 23:33:33 +00004507 /* file modes for subsequent fdopen's on pipe handles */
4508 if (mode == O_TEXT)
4509 {
4510 rd_mode = "rt";
4511 wr_mode = "wt";
4512 }
4513 else
4514 {
4515 rd_mode = "rb";
4516 wr_mode = "wb";
4517 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004518
Victor Stinnerd6f85422010-05-05 23:33:33 +00004519 /* prepare shell references */
4520 if ((shell = getenv("EMXSHELL")) == NULL)
4521 if ((shell = getenv("COMSPEC")) == NULL)
4522 {
4523 errno = ENOENT;
4524 return posix_error();
4525 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004526
Victor Stinnerd6f85422010-05-05 23:33:33 +00004527 sh_name = _getname(shell);
4528 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4529 opt = "/c";
4530 else
4531 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004532
Victor Stinnerd6f85422010-05-05 23:33:33 +00004533 /* save current stdio fds + their flags, and set not inheritable */
4534 i = pipe_err = 0;
4535 while (pipe_err >= 0 && i < 3)
4536 {
4537 pipe_err = stdio[i].handle = dup(i);
4538 stdio[i].flags = fcntl(i, F_GETFD, 0);
4539 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4540 i++;
4541 }
4542 if (pipe_err < 0)
4543 {
4544 /* didn't get them all saved - clean up and bail out */
4545 int saved_err = errno;
4546 while (i-- > 0)
4547 {
4548 close(stdio[i].handle);
4549 }
4550 errno = saved_err;
4551 return posix_error();
4552 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004553
Victor Stinnerd6f85422010-05-05 23:33:33 +00004554 /* create pipe ends */
4555 file_count = 2;
4556 if (n == POPEN_3)
4557 file_count = 3;
4558 i = pipe_err = 0;
4559 while ((pipe_err == 0) && (i < file_count))
4560 pipe_err = pipe((int *)&p_fd[i++]);
4561 if (pipe_err < 0)
4562 {
4563 /* didn't get them all made - clean up and bail out */
4564 while (i-- > 0)
4565 {
4566 close(p_fd[i].wr);
4567 close(p_fd[i].rd);
4568 }
4569 errno = EPIPE;
4570 return posix_error();
4571 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004572
Victor Stinnerd6f85422010-05-05 23:33:33 +00004573 /* change the actual standard IO streams over temporarily,
4574 * making the retained pipe ends non-inheritable
4575 */
4576 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004577
Victor Stinnerd6f85422010-05-05 23:33:33 +00004578 /* - stdin */
4579 if (dup2(p_fd[0].rd, 0) == 0)
4580 {
4581 close(p_fd[0].rd);
4582 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4583 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4584 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4585 {
4586 close(p_fd[0].wr);
4587 pipe_err = -1;
4588 }
4589 }
4590 else
4591 {
4592 pipe_err = -1;
4593 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004594
Victor Stinnerd6f85422010-05-05 23:33:33 +00004595 /* - stdout */
4596 if (pipe_err == 0)
4597 {
4598 if (dup2(p_fd[1].wr, 1) == 1)
4599 {
4600 close(p_fd[1].wr);
4601 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4602 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4603 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4604 {
4605 close(p_fd[1].rd);
4606 pipe_err = -1;
4607 }
4608 }
4609 else
4610 {
4611 pipe_err = -1;
4612 }
4613 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004614
Victor Stinnerd6f85422010-05-05 23:33:33 +00004615 /* - stderr, as required */
4616 if (pipe_err == 0)
4617 switch (n)
4618 {
4619 case POPEN_3:
4620 {
4621 if (dup2(p_fd[2].wr, 2) == 2)
4622 {
4623 close(p_fd[2].wr);
4624 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4625 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4626 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4627 {
4628 close(p_fd[2].rd);
4629 pipe_err = -1;
4630 }
4631 }
4632 else
4633 {
4634 pipe_err = -1;
4635 }
4636 break;
4637 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004638
Victor Stinnerd6f85422010-05-05 23:33:33 +00004639 case POPEN_4:
4640 {
4641 if (dup2(1, 2) != 2)
4642 {
4643 pipe_err = -1;
4644 }
4645 break;
4646 }
4647 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004648
Victor Stinnerd6f85422010-05-05 23:33:33 +00004649 /* spawn the child process */
4650 if (pipe_err == 0)
4651 {
4652 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4653 if (pipe_pid == -1)
4654 {
4655 pipe_err = -1;
4656 }
4657 else
4658 {
4659 /* save the PID into the FILE structure
4660 * NOTE: this implementation doesn't actually
4661 * take advantage of this, but do it for
4662 * completeness - AIM Apr01
4663 */
4664 for (i = 0; i < file_count; i++)
4665 p_s[i]->_pid = pipe_pid;
4666 }
4667 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004668
Victor Stinnerd6f85422010-05-05 23:33:33 +00004669 /* reset standard IO to normal */
4670 for (i = 0; i < 3; i++)
4671 {
4672 dup2(stdio[i].handle, i);
4673 fcntl(i, F_SETFD, stdio[i].flags);
4674 close(stdio[i].handle);
4675 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004676
Victor Stinnerd6f85422010-05-05 23:33:33 +00004677 /* if any remnant problems, clean up and bail out */
4678 if (pipe_err < 0)
4679 {
4680 for (i = 0; i < 3; i++)
4681 {
4682 close(p_fd[i].rd);
4683 close(p_fd[i].wr);
4684 }
4685 errno = EPIPE;
4686 return posix_error_with_filename(cmdstring);
4687 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004688
Victor Stinnerd6f85422010-05-05 23:33:33 +00004689 /* build tuple of file objects to return */
4690 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4691 PyFile_SetBufSize(p_f[0], bufsize);
4692 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4693 PyFile_SetBufSize(p_f[1], bufsize);
4694 if (n == POPEN_3)
4695 {
4696 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4697 PyFile_SetBufSize(p_f[0], bufsize);
4698 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4699 }
4700 else
4701 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004702
Victor Stinnerd6f85422010-05-05 23:33:33 +00004703 /*
4704 * Insert the files we've created into the process dictionary
4705 * all referencing the list with the process handle and the
4706 * initial number of files (see description below in _PyPclose).
4707 * Since if _PyPclose later tried to wait on a process when all
4708 * handles weren't closed, it could create a deadlock with the
4709 * child, we spend some energy here to try to ensure that we
4710 * either insert all file handles into the dictionary or none
4711 * at all. It's a little clumsy with the various popen modes
4712 * and variable number of files involved.
4713 */
4714 if (!_PyPopenProcs)
4715 {
4716 _PyPopenProcs = PyDict_New();
4717 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004718
Victor Stinnerd6f85422010-05-05 23:33:33 +00004719 if (_PyPopenProcs)
4720 {
4721 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4722 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004723
Victor Stinnerd6f85422010-05-05 23:33:33 +00004724 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4725 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004726
Victor Stinnerd6f85422010-05-05 23:33:33 +00004727 procObj = PyList_New(2);
4728 pidObj = PyLong_FromPid(pipe_pid);
4729 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004730
Victor Stinnerd6f85422010-05-05 23:33:33 +00004731 if (procObj && pidObj && intObj)
4732 {
4733 PyList_SetItem(procObj, 0, pidObj);
4734 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004735
Victor Stinnerd6f85422010-05-05 23:33:33 +00004736 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4737 if (fileObj[0])
4738 {
4739 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4740 fileObj[0],
4741 procObj);
4742 }
4743 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4744 if (fileObj[1])
4745 {
4746 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4747 fileObj[1],
4748 procObj);
4749 }
4750 if (file_count >= 3)
4751 {
4752 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4753 if (fileObj[2])
4754 {
4755 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4756 fileObj[2],
4757 procObj);
4758 }
4759 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004760
Victor Stinnerd6f85422010-05-05 23:33:33 +00004761 if (ins_rc[0] < 0 || !fileObj[0] ||
4762 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4763 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4764 {
4765 /* Something failed - remove any dictionary
4766 * entries that did make it.
4767 */
4768 if (!ins_rc[0] && fileObj[0])
4769 {
4770 PyDict_DelItem(_PyPopenProcs,
4771 fileObj[0]);
4772 }
4773 if (!ins_rc[1] && fileObj[1])
4774 {
4775 PyDict_DelItem(_PyPopenProcs,
4776 fileObj[1]);
4777 }
4778 if (!ins_rc[2] && fileObj[2])
4779 {
4780 PyDict_DelItem(_PyPopenProcs,
4781 fileObj[2]);
4782 }
4783 }
4784 }
Tim Peters11b23062003-04-23 02:39:17 +00004785
Victor Stinnerd6f85422010-05-05 23:33:33 +00004786 /*
4787 * Clean up our localized references for the dictionary keys
4788 * and value since PyDict_SetItem will Py_INCREF any copies
4789 * that got placed in the dictionary.
4790 */
4791 Py_XDECREF(procObj);
4792 Py_XDECREF(fileObj[0]);
4793 Py_XDECREF(fileObj[1]);
4794 Py_XDECREF(fileObj[2]);
4795 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004796
Victor Stinnerd6f85422010-05-05 23:33:33 +00004797 /* Child is launched. */
4798 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004799}
4800
4801/*
4802 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4803 * exit code for the child process and return as a result of the close.
4804 *
4805 * This function uses the _PyPopenProcs dictionary in order to map the
4806 * input file pointer to information about the process that was
4807 * originally created by the popen* call that created the file pointer.
4808 * The dictionary uses the file pointer as a key (with one entry
4809 * inserted for each file returned by the original popen* call) and a
4810 * single list object as the value for all files from a single call.
4811 * The list object contains the Win32 process handle at [0], and a file
4812 * count at [1], which is initialized to the total number of file
4813 * handles using that list.
4814 *
4815 * This function closes whichever handle it is passed, and decrements
4816 * the file count in the dictionary for the process handle pointed to
4817 * by this file. On the last close (when the file count reaches zero),
4818 * this function will wait for the child process and then return its
4819 * exit code as the result of the close() operation. This permits the
4820 * files to be closed in any order - it is always the close() of the
4821 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004822 *
4823 * NOTE: This function is currently called with the GIL released.
4824 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004825 */
4826
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004827static int _PyPclose(FILE *file)
4828{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004829 int result;
4830 int exit_code;
4831 pid_t pipe_pid;
4832 PyObject *procObj, *pidObj, *intObj, *fileObj;
4833 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004834#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004835 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004836#endif
4837
Victor Stinnerd6f85422010-05-05 23:33:33 +00004838 /* Close the file handle first, to ensure it can't block the
4839 * child from exiting if it's the last handle.
4840 */
4841 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004842
4843#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004844 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004845#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004846 if (_PyPopenProcs)
4847 {
4848 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4849 (procObj = PyDict_GetItem(_PyPopenProcs,
4850 fileObj)) != NULL &&
4851 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4852 (intObj = PyList_GetItem(procObj,1)) != NULL)
4853 {
4854 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4855 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004856
Victor Stinnerd6f85422010-05-05 23:33:33 +00004857 if (file_count > 1)
4858 {
4859 /* Still other files referencing process */
4860 file_count--;
4861 PyList_SetItem(procObj,1,
4862 PyInt_FromLong((long) file_count));
4863 }
4864 else
4865 {
4866 /* Last file for this process */
4867 if (result != EOF &&
4868 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4869 {
4870 /* extract exit status */
4871 if (WIFEXITED(exit_code))
4872 {
4873 result = WEXITSTATUS(exit_code);
4874 }
4875 else
4876 {
4877 errno = EPIPE;
4878 result = -1;
4879 }
4880 }
4881 else
4882 {
4883 /* Indicate failure - this will cause the file object
4884 * to raise an I/O error and translate the last
4885 * error code from errno. We do have a problem with
4886 * last errors that overlap the normal errno table,
4887 * but that's a consistent problem with the file object.
4888 */
4889 result = -1;
4890 }
4891 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004892
Victor Stinnerd6f85422010-05-05 23:33:33 +00004893 /* Remove this file pointer from dictionary */
4894 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004895
Victor Stinnerd6f85422010-05-05 23:33:33 +00004896 if (PyDict_Size(_PyPopenProcs) == 0)
4897 {
4898 Py_DECREF(_PyPopenProcs);
4899 _PyPopenProcs = NULL;
4900 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004901
Victor Stinnerd6f85422010-05-05 23:33:33 +00004902 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004903
Victor Stinnerd6f85422010-05-05 23:33:33 +00004904 Py_XDECREF(fileObj);
4905 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004906
4907#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004908 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004909#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004910 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004911}
4912
4913#endif /* PYCC_??? */
4914
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004915#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004916
4917/*
4918 * Portable 'popen' replacement for Win32.
4919 *
4920 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4921 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004922 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004923 */
4924
4925#include <malloc.h>
4926#include <io.h>
4927#include <fcntl.h>
4928
4929/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4930#define POPEN_1 1
4931#define POPEN_2 2
4932#define POPEN_3 3
4933#define POPEN_4 4
4934
4935static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004936static int _PyPclose(FILE *file);
4937
4938/*
4939 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004940 * for use when retrieving the process exit code. See _PyPclose() below
4941 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004942 */
4943static PyObject *_PyPopenProcs = NULL;
4944
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004945
4946/* popen that works from a GUI.
4947 *
4948 * The result of this function is a pipe (file) connected to the
4949 * processes stdin or stdout, depending on the requested mode.
4950 */
4951
4952static PyObject *
4953posix_popen(PyObject *self, PyObject *args)
4954{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004955 PyObject *f;
4956 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004957
Victor Stinnerd6f85422010-05-05 23:33:33 +00004958 char *cmdstring;
4959 char *mode = "r";
4960 int bufsize = -1;
4961 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4962 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004963
Victor Stinnerd6f85422010-05-05 23:33:33 +00004964 if (*mode == 'r')
4965 tm = _O_RDONLY;
4966 else if (*mode != 'w') {
4967 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4968 return NULL;
4969 } else
4970 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004971
Victor Stinnerd6f85422010-05-05 23:33:33 +00004972 if (bufsize != -1) {
4973 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4974 return NULL;
4975 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004976
Victor Stinnerd6f85422010-05-05 23:33:33 +00004977 if (*(mode+1) == 't')
4978 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4979 else if (*(mode+1) == 'b')
4980 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4981 else
4982 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004983
Victor Stinnerd6f85422010-05-05 23:33:33 +00004984 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004985}
4986
4987/* Variation on win32pipe.popen
4988 *
4989 * The result of this function is a pipe (file) connected to the
4990 * process's stdin, and a pipe connected to the process's stdout.
4991 */
4992
4993static PyObject *
4994win32_popen2(PyObject *self, PyObject *args)
4995{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004996 PyObject *f;
4997 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004998
Victor Stinnerd6f85422010-05-05 23:33:33 +00004999 char *cmdstring;
5000 char *mode = "t";
5001 int bufsize = -1;
5002 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
5003 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005004
Victor Stinnerd6f85422010-05-05 23:33:33 +00005005 if (*mode == 't')
5006 tm = _O_TEXT;
5007 else if (*mode != 'b') {
5008 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
5009 return NULL;
5010 } else
5011 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005012
Victor Stinnerd6f85422010-05-05 23:33:33 +00005013 if (bufsize != -1) {
5014 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
5015 return NULL;
5016 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005017
Victor Stinnerd6f85422010-05-05 23:33:33 +00005018 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00005019
Victor Stinnerd6f85422010-05-05 23:33:33 +00005020 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005021}
5022
5023/*
5024 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00005025 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005026 * The result of this function is 3 pipes - the process's stdin,
5027 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005028 */
5029
5030static PyObject *
5031win32_popen3(PyObject *self, PyObject *args)
5032{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005033 PyObject *f;
5034 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005035
Victor Stinnerd6f85422010-05-05 23:33:33 +00005036 char *cmdstring;
5037 char *mode = "t";
5038 int bufsize = -1;
5039 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
5040 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005041
Victor Stinnerd6f85422010-05-05 23:33:33 +00005042 if (*mode == 't')
5043 tm = _O_TEXT;
5044 else if (*mode != 'b') {
5045 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
5046 return NULL;
5047 } else
5048 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00005049
Victor Stinnerd6f85422010-05-05 23:33:33 +00005050 if (bufsize != -1) {
5051 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
5052 return NULL;
5053 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005054
Victor Stinnerd6f85422010-05-05 23:33:33 +00005055 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005056
Victor Stinnerd6f85422010-05-05 23:33:33 +00005057 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005058}
5059
5060/*
5061 * Variation on win32pipe.popen
5062 *
Tim Peters5aa91602002-01-30 05:46:57 +00005063 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005064 * and stdout+stderr combined as a single pipe.
5065 */
5066
5067static PyObject *
5068win32_popen4(PyObject *self, PyObject *args)
5069{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005070 PyObject *f;
5071 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005072
Victor Stinnerd6f85422010-05-05 23:33:33 +00005073 char *cmdstring;
5074 char *mode = "t";
5075 int bufsize = -1;
5076 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5077 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005078
Victor Stinnerd6f85422010-05-05 23:33:33 +00005079 if (*mode == 't')
5080 tm = _O_TEXT;
5081 else if (*mode != 'b') {
5082 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5083 return NULL;
5084 } else
5085 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005086
Victor Stinnerd6f85422010-05-05 23:33:33 +00005087 if (bufsize != -1) {
5088 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5089 return NULL;
5090 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005091
Victor Stinnerd6f85422010-05-05 23:33:33 +00005092 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005093
Victor Stinnerd6f85422010-05-05 23:33:33 +00005094 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005095}
5096
Mark Hammond08501372001-01-31 07:30:29 +00005097static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005098_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005099 HANDLE hStdin,
5100 HANDLE hStdout,
5101 HANDLE hStderr,
5102 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005103{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005104 PROCESS_INFORMATION piProcInfo;
5105 STARTUPINFO siStartInfo;
5106 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5107 char *s1,*s2, *s3 = " /c ";
5108 const char *szConsoleSpawn = "w9xpopen.exe";
5109 int i;
5110 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005111
Victor Stinnerd6f85422010-05-05 23:33:33 +00005112 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5113 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005114
Victor Stinnerd6f85422010-05-05 23:33:33 +00005115 s1 = (char *)alloca(i);
5116 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5117 /* x < i, so x fits into an integer */
5118 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005119
Victor Stinnerd6f85422010-05-05 23:33:33 +00005120 /* Explicitly check if we are using COMMAND.COM. If we are
5121 * then use the w9xpopen hack.
5122 */
5123 comshell = s1 + x;
5124 while (comshell >= s1 && *comshell != '\\')
5125 --comshell;
5126 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005127
Victor Stinnerd6f85422010-05-05 23:33:33 +00005128 if (GetVersion() < 0x80000000 &&
5129 _stricmp(comshell, "command.com") != 0) {
5130 /* NT/2000 and not using command.com. */
5131 x = i + strlen(s3) + strlen(cmdstring) + 1;
5132 s2 = (char *)alloca(x);
5133 ZeroMemory(s2, x);
5134 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5135 }
5136 else {
5137 /*
5138 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5139 * the workaround listed in KB: Q150956
5140 */
5141 char modulepath[_MAX_PATH];
5142 struct stat statinfo;
5143 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5144 for (x = i = 0; modulepath[i]; i++)
5145 if (modulepath[i] == SEP)
5146 x = i+1;
5147 modulepath[x] = '\0';
5148 /* Create the full-name to w9xpopen, so we can test it exists */
5149 strncat(modulepath,
5150 szConsoleSpawn,
5151 (sizeof(modulepath)/sizeof(modulepath[0]))
5152 -strlen(modulepath));
5153 if (stat(modulepath, &statinfo) != 0) {
5154 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5155 /* Eeek - file-not-found - possibly an embedding
5156 situation - see if we can locate it in sys.prefix
5157 */
5158 strncpy(modulepath,
5159 Py_GetExecPrefix(),
5160 mplen);
5161 modulepath[mplen-1] = '\0';
5162 if (modulepath[strlen(modulepath)-1] != '\\')
5163 strcat(modulepath, "\\");
5164 strncat(modulepath,
5165 szConsoleSpawn,
5166 mplen-strlen(modulepath));
5167 /* No where else to look - raise an easily identifiable
5168 error, rather than leaving Windows to report
5169 "file not found" - as the user is probably blissfully
5170 unaware this shim EXE is used, and it will confuse them.
5171 (well, it confused me for a while ;-)
5172 */
5173 if (stat(modulepath, &statinfo) != 0) {
5174 PyErr_Format(PyExc_RuntimeError,
5175 "Can not locate '%s' which is needed "
5176 "for popen to work with your shell "
5177 "or platform.",
5178 szConsoleSpawn);
5179 return FALSE;
5180 }
5181 }
5182 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5183 strlen(modulepath) +
5184 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005185
Victor Stinnerd6f85422010-05-05 23:33:33 +00005186 s2 = (char *)alloca(x);
5187 ZeroMemory(s2, x);
5188 /* To maintain correct argument passing semantics,
5189 we pass the command-line as it stands, and allow
5190 quoting to be applied. w9xpopen.exe will then
5191 use its argv vector, and re-quote the necessary
5192 args for the ultimate child process.
5193 */
5194 PyOS_snprintf(
5195 s2, x,
5196 "\"%s\" %s%s%s",
5197 modulepath,
5198 s1,
5199 s3,
5200 cmdstring);
5201 /* Not passing CREATE_NEW_CONSOLE has been known to
5202 cause random failures on win9x. Specifically a
5203 dialog:
5204 "Your program accessed mem currently in use at xxx"
5205 and a hopeful warning about the stability of your
5206 system.
5207 Cost is Ctrl+C won't kill children, but anyone
5208 who cares can have a go!
5209 */
5210 dwProcessFlags |= CREATE_NEW_CONSOLE;
5211 }
5212 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005213
Victor Stinnerd6f85422010-05-05 23:33:33 +00005214 /* Could be an else here to try cmd.exe / command.com in the path
5215 Now we'll just error out.. */
5216 else {
5217 PyErr_SetString(PyExc_RuntimeError,
5218 "Cannot locate a COMSPEC environment variable to "
5219 "use as the shell");
5220 return FALSE;
5221 }
Tim Peters5aa91602002-01-30 05:46:57 +00005222
Victor Stinnerd6f85422010-05-05 23:33:33 +00005223 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5224 siStartInfo.cb = sizeof(STARTUPINFO);
5225 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5226 siStartInfo.hStdInput = hStdin;
5227 siStartInfo.hStdOutput = hStdout;
5228 siStartInfo.hStdError = hStderr;
5229 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005230
Victor Stinnerd6f85422010-05-05 23:33:33 +00005231 if (CreateProcess(NULL,
5232 s2,
5233 NULL,
5234 NULL,
5235 TRUE,
5236 dwProcessFlags,
5237 NULL,
5238 NULL,
5239 &siStartInfo,
5240 &piProcInfo) ) {
5241 /* Close the handles now so anyone waiting is woken. */
5242 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005243
Victor Stinnerd6f85422010-05-05 23:33:33 +00005244 /* Return process handle */
5245 *hProcess = piProcInfo.hProcess;
5246 return TRUE;
5247 }
5248 win32_error("CreateProcess", s2);
5249 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005250}
5251
5252/* The following code is based off of KB: Q190351 */
5253
5254static PyObject *
5255_PyPopen(char *cmdstring, int mode, int n)
5256{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005257 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5258 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5259 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005260
Victor Stinnerd6f85422010-05-05 23:33:33 +00005261 SECURITY_ATTRIBUTES saAttr;
5262 BOOL fSuccess;
5263 int fd1, fd2, fd3;
5264 FILE *f1, *f2, *f3;
5265 long file_count;
5266 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005267
Victor Stinnerd6f85422010-05-05 23:33:33 +00005268 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5269 saAttr.bInheritHandle = TRUE;
5270 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005271
Victor Stinnerd6f85422010-05-05 23:33:33 +00005272 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5273 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005274
Victor Stinnerd6f85422010-05-05 23:33:33 +00005275 /* Create new output read handle and the input write handle. Set
5276 * the inheritance properties to FALSE. Otherwise, the child inherits
5277 * these handles; resulting in non-closeable handles to the pipes
5278 * being created. */
5279 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5280 GetCurrentProcess(), &hChildStdinWrDup, 0,
5281 FALSE,
5282 DUPLICATE_SAME_ACCESS);
5283 if (!fSuccess)
5284 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005285
Victor Stinnerd6f85422010-05-05 23:33:33 +00005286 /* Close the inheritable version of ChildStdin
5287 that we're using. */
5288 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005289
Victor Stinnerd6f85422010-05-05 23:33:33 +00005290 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5291 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005292
Victor Stinnerd6f85422010-05-05 23:33:33 +00005293 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5294 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5295 FALSE, DUPLICATE_SAME_ACCESS);
5296 if (!fSuccess)
5297 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005298
Victor Stinnerd6f85422010-05-05 23:33:33 +00005299 /* Close the inheritable version of ChildStdout
5300 that we're using. */
5301 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005302
Victor Stinnerd6f85422010-05-05 23:33:33 +00005303 if (n != POPEN_4) {
5304 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5305 return win32_error("CreatePipe", NULL);
5306 fSuccess = DuplicateHandle(GetCurrentProcess(),
5307 hChildStderrRd,
5308 GetCurrentProcess(),
5309 &hChildStderrRdDup, 0,
5310 FALSE, DUPLICATE_SAME_ACCESS);
5311 if (!fSuccess)
5312 return win32_error("DuplicateHandle", NULL);
5313 /* Close the inheritable version of ChildStdErr that we're using. */
5314 CloseHandle(hChildStderrRd);
5315 }
Tim Peters5aa91602002-01-30 05:46:57 +00005316
Victor Stinnerd6f85422010-05-05 23:33:33 +00005317 switch (n) {
5318 case POPEN_1:
5319 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5320 case _O_WRONLY | _O_TEXT:
5321 /* Case for writing to child Stdin in text mode. */
5322 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5323 f1 = _fdopen(fd1, "w");
5324 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5325 PyFile_SetBufSize(f, 0);
5326 /* We don't care about these pipes anymore, so close them. */
5327 CloseHandle(hChildStdoutRdDup);
5328 CloseHandle(hChildStderrRdDup);
5329 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005330
Victor Stinnerd6f85422010-05-05 23:33:33 +00005331 case _O_RDONLY | _O_TEXT:
5332 /* Case for reading from child Stdout in text mode. */
5333 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5334 f1 = _fdopen(fd1, "r");
5335 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5336 PyFile_SetBufSize(f, 0);
5337 /* We don't care about these pipes anymore, so close them. */
5338 CloseHandle(hChildStdinWrDup);
5339 CloseHandle(hChildStderrRdDup);
5340 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341
Victor Stinnerd6f85422010-05-05 23:33:33 +00005342 case _O_RDONLY | _O_BINARY:
5343 /* Case for readinig from child Stdout in binary mode. */
5344 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5345 f1 = _fdopen(fd1, "rb");
5346 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5347 PyFile_SetBufSize(f, 0);
5348 /* We don't care about these pipes anymore, so close them. */
5349 CloseHandle(hChildStdinWrDup);
5350 CloseHandle(hChildStderrRdDup);
5351 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005352
Victor Stinnerd6f85422010-05-05 23:33:33 +00005353 case _O_WRONLY | _O_BINARY:
5354 /* Case for writing to child Stdin in binary mode. */
5355 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5356 f1 = _fdopen(fd1, "wb");
5357 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5358 PyFile_SetBufSize(f, 0);
5359 /* We don't care about these pipes anymore, so close them. */
5360 CloseHandle(hChildStdoutRdDup);
5361 CloseHandle(hChildStderrRdDup);
5362 break;
5363 }
5364 file_count = 1;
5365 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005366
Victor Stinnerd6f85422010-05-05 23:33:33 +00005367 case POPEN_2:
5368 case POPEN_4:
5369 {
5370 char *m1, *m2;
5371 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005372
Victor Stinnerd6f85422010-05-05 23:33:33 +00005373 if (mode & _O_TEXT) {
5374 m1 = "r";
5375 m2 = "w";
5376 } else {
5377 m1 = "rb";
5378 m2 = "wb";
5379 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005380
Victor Stinnerd6f85422010-05-05 23:33:33 +00005381 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5382 f1 = _fdopen(fd1, m2);
5383 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5384 f2 = _fdopen(fd2, m1);
5385 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5386 PyFile_SetBufSize(p1, 0);
5387 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5388 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005389
Victor Stinnerd6f85422010-05-05 23:33:33 +00005390 if (n != 4)
5391 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005392
Victor Stinnerd6f85422010-05-05 23:33:33 +00005393 f = PyTuple_Pack(2,p1,p2);
5394 Py_XDECREF(p1);
5395 Py_XDECREF(p2);
5396 file_count = 2;
5397 break;
5398 }
Tim Peters5aa91602002-01-30 05:46:57 +00005399
Victor Stinnerd6f85422010-05-05 23:33:33 +00005400 case POPEN_3:
5401 {
5402 char *m1, *m2;
5403 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005404
Victor Stinnerd6f85422010-05-05 23:33:33 +00005405 if (mode & _O_TEXT) {
5406 m1 = "r";
5407 m2 = "w";
5408 } else {
5409 m1 = "rb";
5410 m2 = "wb";
5411 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005412
Victor Stinnerd6f85422010-05-05 23:33:33 +00005413 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5414 f1 = _fdopen(fd1, m2);
5415 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5416 f2 = _fdopen(fd2, m1);
5417 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5418 f3 = _fdopen(fd3, m1);
5419 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5420 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5421 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5422 PyFile_SetBufSize(p1, 0);
5423 PyFile_SetBufSize(p2, 0);
5424 PyFile_SetBufSize(p3, 0);
5425 f = PyTuple_Pack(3,p1,p2,p3);
5426 Py_XDECREF(p1);
5427 Py_XDECREF(p2);
5428 Py_XDECREF(p3);
5429 file_count = 3;
5430 break;
5431 }
5432 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005433
Victor Stinnerd6f85422010-05-05 23:33:33 +00005434 if (n == POPEN_4) {
5435 if (!_PyPopenCreateProcess(cmdstring,
5436 hChildStdinRd,
5437 hChildStdoutWr,
5438 hChildStdoutWr,
5439 &hProcess))
5440 return NULL;
5441 }
5442 else {
5443 if (!_PyPopenCreateProcess(cmdstring,
5444 hChildStdinRd,
5445 hChildStdoutWr,
5446 hChildStderrWr,
5447 &hProcess))
5448 return NULL;
5449 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005450
Victor Stinnerd6f85422010-05-05 23:33:33 +00005451 /*
5452 * Insert the files we've created into the process dictionary
5453 * all referencing the list with the process handle and the
5454 * initial number of files (see description below in _PyPclose).
5455 * Since if _PyPclose later tried to wait on a process when all
5456 * handles weren't closed, it could create a deadlock with the
5457 * child, we spend some energy here to try to ensure that we
5458 * either insert all file handles into the dictionary or none
5459 * at all. It's a little clumsy with the various popen modes
5460 * and variable number of files involved.
5461 */
5462 if (!_PyPopenProcs) {
5463 _PyPopenProcs = PyDict_New();
5464 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005465
Victor Stinnerd6f85422010-05-05 23:33:33 +00005466 if (_PyPopenProcs) {
5467 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5468 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005469
Victor Stinnerd6f85422010-05-05 23:33:33 +00005470 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5471 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005472
Victor Stinnerd6f85422010-05-05 23:33:33 +00005473 procObj = PyList_New(2);
5474 hProcessObj = PyLong_FromVoidPtr(hProcess);
5475 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005476
Victor Stinnerd6f85422010-05-05 23:33:33 +00005477 if (procObj && hProcessObj && intObj) {
5478 PyList_SetItem(procObj,0,hProcessObj);
5479 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005480
Victor Stinnerd6f85422010-05-05 23:33:33 +00005481 fileObj[0] = PyLong_FromVoidPtr(f1);
5482 if (fileObj[0]) {
5483 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5484 fileObj[0],
5485 procObj);
5486 }
5487 if (file_count >= 2) {
5488 fileObj[1] = PyLong_FromVoidPtr(f2);
5489 if (fileObj[1]) {
5490 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5491 fileObj[1],
5492 procObj);
5493 }
5494 }
5495 if (file_count >= 3) {
5496 fileObj[2] = PyLong_FromVoidPtr(f3);
5497 if (fileObj[2]) {
5498 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5499 fileObj[2],
5500 procObj);
5501 }
5502 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005503
Victor Stinnerd6f85422010-05-05 23:33:33 +00005504 if (ins_rc[0] < 0 || !fileObj[0] ||
5505 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5506 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5507 /* Something failed - remove any dictionary
5508 * entries that did make it.
5509 */
5510 if (!ins_rc[0] && fileObj[0]) {
5511 PyDict_DelItem(_PyPopenProcs,
5512 fileObj[0]);
5513 }
5514 if (!ins_rc[1] && fileObj[1]) {
5515 PyDict_DelItem(_PyPopenProcs,
5516 fileObj[1]);
5517 }
5518 if (!ins_rc[2] && fileObj[2]) {
5519 PyDict_DelItem(_PyPopenProcs,
5520 fileObj[2]);
5521 }
5522 }
5523 }
Tim Peters5aa91602002-01-30 05:46:57 +00005524
Victor Stinnerd6f85422010-05-05 23:33:33 +00005525 /*
5526 * Clean up our localized references for the dictionary keys
5527 * and value since PyDict_SetItem will Py_INCREF any copies
5528 * that got placed in the dictionary.
5529 */
5530 Py_XDECREF(procObj);
5531 Py_XDECREF(fileObj[0]);
5532 Py_XDECREF(fileObj[1]);
5533 Py_XDECREF(fileObj[2]);
5534 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005535
Victor Stinnerd6f85422010-05-05 23:33:33 +00005536 /* Child is launched. Close the parents copy of those pipe
5537 * handles that only the child should have open. You need to
5538 * make sure that no handles to the write end of the output pipe
5539 * are maintained in this process or else the pipe will not close
5540 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005541
Victor Stinnerd6f85422010-05-05 23:33:33 +00005542 if (!CloseHandle(hChildStdinRd))
5543 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005544
Victor Stinnerd6f85422010-05-05 23:33:33 +00005545 if (!CloseHandle(hChildStdoutWr))
5546 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005547
Victor Stinnerd6f85422010-05-05 23:33:33 +00005548 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5549 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005550
Victor Stinnerd6f85422010-05-05 23:33:33 +00005551 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005552}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005553
5554/*
5555 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5556 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005557 *
5558 * This function uses the _PyPopenProcs dictionary in order to map the
5559 * input file pointer to information about the process that was
5560 * originally created by the popen* call that created the file pointer.
5561 * The dictionary uses the file pointer as a key (with one entry
5562 * inserted for each file returned by the original popen* call) and a
5563 * single list object as the value for all files from a single call.
5564 * The list object contains the Win32 process handle at [0], and a file
5565 * count at [1], which is initialized to the total number of file
5566 * handles using that list.
5567 *
5568 * This function closes whichever handle it is passed, and decrements
5569 * the file count in the dictionary for the process handle pointed to
5570 * by this file. On the last close (when the file count reaches zero),
5571 * this function will wait for the child process and then return its
5572 * exit code as the result of the close() operation. This permits the
5573 * files to be closed in any order - it is always the close() of the
5574 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005575 *
5576 * NOTE: This function is currently called with the GIL released.
5577 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005578 */
Tim Peters736aa322000-09-01 06:51:24 +00005579
Fredrik Lundh56055a42000-07-23 19:47:12 +00005580static int _PyPclose(FILE *file)
5581{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005582 int result;
5583 DWORD exit_code;
5584 HANDLE hProcess;
5585 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5586 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005587#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005588 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005589#endif
5590
Victor Stinnerd6f85422010-05-05 23:33:33 +00005591 /* Close the file handle first, to ensure it can't block the
5592 * child from exiting if it's the last handle.
5593 */
5594 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005595#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005596 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005597#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005598 if (_PyPopenProcs) {
5599 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5600 (procObj = PyDict_GetItem(_PyPopenProcs,
5601 fileObj)) != NULL &&
5602 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5603 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005604
Victor Stinnerd6f85422010-05-05 23:33:33 +00005605 hProcess = PyLong_AsVoidPtr(hProcessObj);
5606 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005607
Victor Stinnerd6f85422010-05-05 23:33:33 +00005608 if (file_count > 1) {
5609 /* Still other files referencing process */
5610 file_count--;
5611 PyList_SetItem(procObj,1,
5612 PyInt_FromLong(file_count));
5613 } else {
5614 /* Last file for this process */
5615 if (result != EOF &&
5616 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5617 GetExitCodeProcess(hProcess, &exit_code)) {
5618 /* Possible truncation here in 16-bit environments, but
5619 * real exit codes are just the lower byte in any event.
5620 */
5621 result = exit_code;
5622 } else {
5623 /* Indicate failure - this will cause the file object
5624 * to raise an I/O error and translate the last Win32
5625 * error code from errno. We do have a problem with
5626 * last errors that overlap the normal errno table,
5627 * but that's a consistent problem with the file object.
5628 */
5629 if (result != EOF) {
5630 /* If the error wasn't from the fclose(), then
5631 * set errno for the file object error handling.
5632 */
5633 errno = GetLastError();
5634 }
5635 result = -1;
5636 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005637
Victor Stinnerd6f85422010-05-05 23:33:33 +00005638 /* Free up the native handle at this point */
5639 CloseHandle(hProcess);
5640 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005641
Victor Stinnerd6f85422010-05-05 23:33:33 +00005642 /* Remove this file pointer from dictionary */
5643 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005644
Victor Stinnerd6f85422010-05-05 23:33:33 +00005645 if (PyDict_Size(_PyPopenProcs) == 0) {
5646 Py_DECREF(_PyPopenProcs);
5647 _PyPopenProcs = NULL;
5648 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005649
Victor Stinnerd6f85422010-05-05 23:33:33 +00005650 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005651
Victor Stinnerd6f85422010-05-05 23:33:33 +00005652 Py_XDECREF(fileObj);
5653 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005654
Tim Peters736aa322000-09-01 06:51:24 +00005655#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005656 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005657#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005658 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005659}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005660
5661#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005663posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005664{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005665 char *name;
5666 char *mode = "r";
5667 int bufsize = -1;
5668 FILE *fp;
5669 PyObject *f;
5670 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5671 return NULL;
5672 /* Strip mode of binary or text modifiers */
5673 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5674 mode = "r";
5675 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5676 mode = "w";
5677 Py_BEGIN_ALLOW_THREADS
5678 fp = popen(name, mode);
5679 Py_END_ALLOW_THREADS
5680 if (fp == NULL)
5681 return posix_error();
5682 f = PyFile_FromFile(fp, name, mode, pclose);
5683 if (f != NULL)
5684 PyFile_SetBufSize(f, bufsize);
5685 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005686}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005687
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005688#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005689#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005691
Guido van Rossumb6775db1994-08-01 11:34:53 +00005692#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005694"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005695Set the current process's user id.");
5696
Barry Warsaw53699e91996-12-10 23:23:01 +00005697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005698posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005699{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005700 long uid_arg;
5701 uid_t uid;
5702 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5703 return NULL;
5704 uid = uid_arg;
5705 if (uid != uid_arg) {
5706 PyErr_SetString(PyExc_OverflowError, "user id too big");
5707 return NULL;
5708 }
5709 if (setuid(uid) < 0)
5710 return posix_error();
5711 Py_INCREF(Py_None);
5712 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005713}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005714#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005715
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005716
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005717#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005718PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005719"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720Set the current process's effective user id.");
5721
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005722static PyObject *
5723posix_seteuid (PyObject *self, PyObject *args)
5724{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005725 long euid_arg;
5726 uid_t euid;
5727 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5728 return NULL;
5729 euid = euid_arg;
5730 if (euid != euid_arg) {
5731 PyErr_SetString(PyExc_OverflowError, "user id too big");
5732 return NULL;
5733 }
5734 if (seteuid(euid) < 0) {
5735 return posix_error();
5736 } else {
5737 Py_INCREF(Py_None);
5738 return Py_None;
5739 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005740}
5741#endif /* HAVE_SETEUID */
5742
5743#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005744PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005745"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005746Set the current process's effective group id.");
5747
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005748static PyObject *
5749posix_setegid (PyObject *self, PyObject *args)
5750{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005751 long egid_arg;
5752 gid_t egid;
5753 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5754 return NULL;
5755 egid = egid_arg;
5756 if (egid != egid_arg) {
5757 PyErr_SetString(PyExc_OverflowError, "group id too big");
5758 return NULL;
5759 }
5760 if (setegid(egid) < 0) {
5761 return posix_error();
5762 } else {
5763 Py_INCREF(Py_None);
5764 return Py_None;
5765 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005766}
5767#endif /* HAVE_SETEGID */
5768
5769#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005770PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005771"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005772Set the current process's real and effective user ids.");
5773
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005774static PyObject *
5775posix_setreuid (PyObject *self, PyObject *args)
5776{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005777 long ruid_arg, euid_arg;
5778 uid_t ruid, euid;
5779 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5780 return NULL;
5781 if (ruid_arg == -1)
5782 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5783 else
5784 ruid = ruid_arg; /* otherwise, assign from our long */
5785 if (euid_arg == -1)
5786 euid = (uid_t)-1;
5787 else
5788 euid = euid_arg;
5789 if ((euid_arg != -1 && euid != euid_arg) ||
5790 (ruid_arg != -1 && ruid != ruid_arg)) {
5791 PyErr_SetString(PyExc_OverflowError, "user id too big");
5792 return NULL;
5793 }
5794 if (setreuid(ruid, euid) < 0) {
5795 return posix_error();
5796 } else {
5797 Py_INCREF(Py_None);
5798 return Py_None;
5799 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005800}
5801#endif /* HAVE_SETREUID */
5802
5803#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005804PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005805"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005806Set the current process's real and effective group ids.");
5807
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005808static PyObject *
5809posix_setregid (PyObject *self, PyObject *args)
5810{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005811 long rgid_arg, egid_arg;
5812 gid_t rgid, egid;
5813 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5814 return NULL;
5815 if (rgid_arg == -1)
5816 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5817 else
5818 rgid = rgid_arg; /* otherwise, assign from our long */
5819 if (egid_arg == -1)
5820 egid = (gid_t)-1;
5821 else
5822 egid = egid_arg;
5823 if ((egid_arg != -1 && egid != egid_arg) ||
5824 (rgid_arg != -1 && rgid != rgid_arg)) {
5825 PyErr_SetString(PyExc_OverflowError, "group id too big");
5826 return NULL;
5827 }
5828 if (setregid(rgid, egid) < 0) {
5829 return posix_error();
5830 } else {
5831 Py_INCREF(Py_None);
5832 return Py_None;
5833 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005834}
5835#endif /* HAVE_SETREGID */
5836
Guido van Rossumb6775db1994-08-01 11:34:53 +00005837#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005838PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005839"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005840Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005841
Barry Warsaw53699e91996-12-10 23:23:01 +00005842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005843posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005844{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005845 long gid_arg;
5846 gid_t gid;
5847 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5848 return NULL;
5849 gid = gid_arg;
5850 if (gid != gid_arg) {
5851 PyErr_SetString(PyExc_OverflowError, "group id too big");
5852 return NULL;
5853 }
5854 if (setgid(gid) < 0)
5855 return posix_error();
5856 Py_INCREF(Py_None);
5857 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005858}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005859#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005860
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005861#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005863"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005865
5866static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005867posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005868{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005869 int i, len;
5870 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005871
Victor Stinnerd6f85422010-05-05 23:33:33 +00005872 if (!PySequence_Check(groups)) {
5873 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5874 return NULL;
5875 }
5876 len = PySequence_Size(groups);
5877 if (len > MAX_GROUPS) {
5878 PyErr_SetString(PyExc_ValueError, "too many groups");
5879 return NULL;
5880 }
5881 for(i = 0; i < len; i++) {
5882 PyObject *elem;
5883 elem = PySequence_GetItem(groups, i);
5884 if (!elem)
5885 return NULL;
5886 if (!PyInt_Check(elem)) {
5887 if (!PyLong_Check(elem)) {
5888 PyErr_SetString(PyExc_TypeError,
5889 "groups must be integers");
5890 Py_DECREF(elem);
5891 return NULL;
5892 } else {
5893 unsigned long x = PyLong_AsUnsignedLong(elem);
5894 if (PyErr_Occurred()) {
5895 PyErr_SetString(PyExc_TypeError,
5896 "group id too big");
5897 Py_DECREF(elem);
5898 return NULL;
5899 }
5900 grouplist[i] = x;
5901 /* read back to see if it fits in gid_t */
5902 if (grouplist[i] != x) {
5903 PyErr_SetString(PyExc_TypeError,
5904 "group id too big");
5905 Py_DECREF(elem);
5906 return NULL;
5907 }
5908 }
5909 } else {
5910 long x = PyInt_AsLong(elem);
5911 grouplist[i] = x;
5912 if (grouplist[i] != x) {
5913 PyErr_SetString(PyExc_TypeError,
5914 "group id too big");
5915 Py_DECREF(elem);
5916 return NULL;
5917 }
5918 }
5919 Py_DECREF(elem);
5920 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005921
Victor Stinnerd6f85422010-05-05 23:33:33 +00005922 if (setgroups(len, grouplist) < 0)
5923 return posix_error();
5924 Py_INCREF(Py_None);
5925 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005926}
5927#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005928
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005929#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005930static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005931wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005932{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005933 PyObject *result;
5934 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005935
Victor Stinnerd6f85422010-05-05 23:33:33 +00005936 if (pid == -1)
5937 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005938
Victor Stinnerd6f85422010-05-05 23:33:33 +00005939 if (struct_rusage == NULL) {
5940 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5941 if (m == NULL)
5942 return NULL;
5943 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5944 Py_DECREF(m);
5945 if (struct_rusage == NULL)
5946 return NULL;
5947 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005948
Victor Stinnerd6f85422010-05-05 23:33:33 +00005949 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5950 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5951 if (!result)
5952 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005953
5954#ifndef doubletime
5955#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5956#endif
5957
Victor Stinnerd6f85422010-05-05 23:33:33 +00005958 PyStructSequence_SET_ITEM(result, 0,
5959 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5960 PyStructSequence_SET_ITEM(result, 1,
5961 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00005962#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00005963 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5964 SET_INT(result, 2, ru->ru_maxrss);
5965 SET_INT(result, 3, ru->ru_ixrss);
5966 SET_INT(result, 4, ru->ru_idrss);
5967 SET_INT(result, 5, ru->ru_isrss);
5968 SET_INT(result, 6, ru->ru_minflt);
5969 SET_INT(result, 7, ru->ru_majflt);
5970 SET_INT(result, 8, ru->ru_nswap);
5971 SET_INT(result, 9, ru->ru_inblock);
5972 SET_INT(result, 10, ru->ru_oublock);
5973 SET_INT(result, 11, ru->ru_msgsnd);
5974 SET_INT(result, 12, ru->ru_msgrcv);
5975 SET_INT(result, 13, ru->ru_nsignals);
5976 SET_INT(result, 14, ru->ru_nvcsw);
5977 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00005978#undef SET_INT
5979
Victor Stinnerd6f85422010-05-05 23:33:33 +00005980 if (PyErr_Occurred()) {
5981 Py_DECREF(result);
5982 return NULL;
5983 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005984
Victor Stinnerd6f85422010-05-05 23:33:33 +00005985 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005986}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005987#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005988
5989#ifdef HAVE_WAIT3
5990PyDoc_STRVAR(posix_wait3__doc__,
5991"wait3(options) -> (pid, status, rusage)\n\n\
5992Wait for completion of a child process.");
5993
5994static PyObject *
5995posix_wait3(PyObject *self, PyObject *args)
5996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005997 pid_t pid;
5998 int options;
5999 struct rusage ru;
6000 WAIT_TYPE status;
6001 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006002
Victor Stinnerd6f85422010-05-05 23:33:33 +00006003 if (!PyArg_ParseTuple(args, "i:wait3", &options))
6004 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006005
Victor Stinnerd6f85422010-05-05 23:33:33 +00006006 Py_BEGIN_ALLOW_THREADS
6007 pid = wait3(&status, options, &ru);
6008 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006009
Victor Stinnerd6f85422010-05-05 23:33:33 +00006010 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006011}
6012#endif /* HAVE_WAIT3 */
6013
6014#ifdef HAVE_WAIT4
6015PyDoc_STRVAR(posix_wait4__doc__,
6016"wait4(pid, options) -> (pid, status, rusage)\n\n\
6017Wait for completion of a given child process.");
6018
6019static PyObject *
6020posix_wait4(PyObject *self, PyObject *args)
6021{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006022 pid_t pid;
6023 int options;
6024 struct rusage ru;
6025 WAIT_TYPE status;
6026 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00006027
Victor Stinnerd6f85422010-05-05 23:33:33 +00006028 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
6029 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00006030
Victor Stinnerd6f85422010-05-05 23:33:33 +00006031 Py_BEGIN_ALLOW_THREADS
6032 pid = wait4(pid, &status, options, &ru);
6033 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00006034
Victor Stinnerd6f85422010-05-05 23:33:33 +00006035 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00006036}
6037#endif /* HAVE_WAIT4 */
6038
Guido van Rossumb6775db1994-08-01 11:34:53 +00006039#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006040PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006041"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006042Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Barry Warsaw53699e91996-12-10 23:23:01 +00006044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006045posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00006046{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006047 pid_t pid;
6048 int options;
6049 WAIT_TYPE status;
6050 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006051
Victor Stinnerd6f85422010-05-05 23:33:33 +00006052 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6053 return NULL;
6054 Py_BEGIN_ALLOW_THREADS
6055 pid = waitpid(pid, &status, options);
6056 Py_END_ALLOW_THREADS
6057 if (pid == -1)
6058 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006059
Victor Stinnerd6f85422010-05-05 23:33:33 +00006060 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006061}
6062
Tim Petersab034fa2002-02-01 11:27:43 +00006063#elif defined(HAVE_CWAIT)
6064
6065/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006066PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006067"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006068"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006069
6070static PyObject *
6071posix_waitpid(PyObject *self, PyObject *args)
6072{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006073 Py_intptr_t pid;
6074 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006075
Victor Stinnerd6f85422010-05-05 23:33:33 +00006076 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6077 return NULL;
6078 Py_BEGIN_ALLOW_THREADS
6079 pid = _cwait(&status, pid, options);
6080 Py_END_ALLOW_THREADS
6081 if (pid == -1)
6082 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006083
Victor Stinnerd6f85422010-05-05 23:33:33 +00006084 /* shift the status left a byte so this is more like the POSIX waitpid */
6085 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006086}
6087#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006088
Guido van Rossumad0ee831995-03-01 10:34:45 +00006089#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006091"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006093
Barry Warsaw53699e91996-12-10 23:23:01 +00006094static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006095posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006096{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006097 pid_t pid;
6098 WAIT_TYPE status;
6099 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006100
Victor Stinnerd6f85422010-05-05 23:33:33 +00006101 Py_BEGIN_ALLOW_THREADS
6102 pid = wait(&status);
6103 Py_END_ALLOW_THREADS
6104 if (pid == -1)
6105 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006106
Victor Stinnerd6f85422010-05-05 23:33:33 +00006107 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006108}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006109#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006112PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006113"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006114Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006115
Barry Warsaw53699e91996-12-10 23:23:01 +00006116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006117posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006118{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006119#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006120 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006121#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006122#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006123 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006124#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006125 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006126#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006127#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006128}
6129
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006130
Guido van Rossumb6775db1994-08-01 11:34:53 +00006131#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006133"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006135
Barry Warsaw53699e91996-12-10 23:23:01 +00006136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006137posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006138{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006139 PyObject* v;
6140 char buf[MAXPATHLEN];
6141 char *path;
6142 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006143#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006144 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006145#endif
6146
Victor Stinnerd6f85422010-05-05 23:33:33 +00006147 if (!PyArg_ParseTuple(args, "et:readlink",
6148 Py_FileSystemDefaultEncoding, &path))
6149 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006150#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006151 v = PySequence_GetItem(args, 0);
6152 if (v == NULL) {
6153 PyMem_Free(path);
6154 return NULL;
6155 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006156
Victor Stinnerd6f85422010-05-05 23:33:33 +00006157 if (PyUnicode_Check(v)) {
6158 arg_is_unicode = 1;
6159 }
6160 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006161#endif
6162
Victor Stinnerd6f85422010-05-05 23:33:33 +00006163 Py_BEGIN_ALLOW_THREADS
6164 n = readlink(path, buf, (int) sizeof buf);
6165 Py_END_ALLOW_THREADS
6166 if (n < 0)
6167 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006168
Victor Stinnerd6f85422010-05-05 23:33:33 +00006169 PyMem_Free(path);
6170 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006171#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006172 if (arg_is_unicode) {
6173 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006174
Victor Stinnerd6f85422010-05-05 23:33:33 +00006175 w = PyUnicode_FromEncodedObject(v,
6176 Py_FileSystemDefaultEncoding,
6177 "strict");
6178 if (w != NULL) {
6179 Py_DECREF(v);
6180 v = w;
6181 }
6182 else {
6183 /* fall back to the original byte string, as
6184 discussed in patch #683592 */
6185 PyErr_Clear();
6186 }
6187 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006188#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006189 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006190}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006191#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006193
Guido van Rossumb6775db1994-08-01 11:34:53 +00006194#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006195PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006196"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006197Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006198
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006200posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006201{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006202 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006203}
6204#endif /* HAVE_SYMLINK */
6205
6206
6207#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006208#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6209static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006210system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006211{
6212 ULONG value = 0;
6213
6214 Py_BEGIN_ALLOW_THREADS
6215 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6216 Py_END_ALLOW_THREADS
6217
6218 return value;
6219}
6220
6221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006222posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006223{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006224 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006225 return Py_BuildValue("ddddd",
6226 (double)0 /* t.tms_utime / HZ */,
6227 (double)0 /* t.tms_stime / HZ */,
6228 (double)0 /* t.tms_cutime / HZ */,
6229 (double)0 /* t.tms_cstime / HZ */,
6230 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006231}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006232#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006233#define NEED_TICKS_PER_SECOND
6234static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006235static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006236posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006237{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006238 struct tms t;
6239 clock_t c;
6240 errno = 0;
6241 c = times(&t);
6242 if (c == (clock_t) -1)
6243 return posix_error();
6244 return Py_BuildValue("ddddd",
6245 (double)t.tms_utime / ticks_per_second,
6246 (double)t.tms_stime / ticks_per_second,
6247 (double)t.tms_cutime / ticks_per_second,
6248 (double)t.tms_cstime / ticks_per_second,
6249 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006250}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006251#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006252#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006253
6254
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006255#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006256#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006257static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006258posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006259{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006260 FILETIME create, exit, kernel, user;
6261 HANDLE hProc;
6262 hProc = GetCurrentProcess();
6263 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6264 /* The fields of a FILETIME structure are the hi and lo part
6265 of a 64-bit value expressed in 100 nanosecond units.
6266 1e7 is one second in such units; 1e-7 the inverse.
6267 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6268 */
6269 return Py_BuildValue(
6270 "ddddd",
6271 (double)(user.dwHighDateTime*429.4967296 +
6272 user.dwLowDateTime*1e-7),
6273 (double)(kernel.dwHighDateTime*429.4967296 +
6274 kernel.dwLowDateTime*1e-7),
6275 (double)0,
6276 (double)0,
6277 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006278}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006279#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006280
6281#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006283"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006285#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006287
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006288#ifdef HAVE_GETSID
6289PyDoc_STRVAR(posix_getsid__doc__,
6290"getsid(pid) -> sid\n\n\
6291Call the system call getsid().");
6292
6293static PyObject *
6294posix_getsid(PyObject *self, PyObject *args)
6295{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006296 pid_t pid;
6297 int sid;
6298 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6299 return NULL;
6300 sid = getsid(pid);
6301 if (sid < 0)
6302 return posix_error();
6303 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006304}
6305#endif /* HAVE_GETSID */
6306
6307
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006309PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006310"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006312
Barry Warsaw53699e91996-12-10 23:23:01 +00006313static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006314posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006315{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006316 if (setsid() < 0)
6317 return posix_error();
6318 Py_INCREF(Py_None);
6319 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006320}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006322
Guido van Rossumb6775db1994-08-01 11:34:53 +00006323#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006324PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006325"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006326Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Barry Warsaw53699e91996-12-10 23:23:01 +00006328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006329posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006330{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006331 pid_t pid;
6332 int pgrp;
6333 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6334 return NULL;
6335 if (setpgid(pid, pgrp) < 0)
6336 return posix_error();
6337 Py_INCREF(Py_None);
6338 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006339}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006340#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006342
Guido van Rossumb6775db1994-08-01 11:34:53 +00006343#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006344PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006345"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006347
Barry Warsaw53699e91996-12-10 23:23:01 +00006348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006349posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006350{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006351 int fd;
6352 pid_t pgid;
6353 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6354 return NULL;
6355 pgid = tcgetpgrp(fd);
6356 if (pgid < 0)
6357 return posix_error();
6358 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006359}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006361
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006362
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006365"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006366Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006367
Barry Warsaw53699e91996-12-10 23:23:01 +00006368static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006369posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006370{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006371 int fd;
6372 pid_t pgid;
6373 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6374 return NULL;
6375 if (tcsetpgrp(fd, pgid) < 0)
6376 return posix_error();
6377 Py_INCREF(Py_None);
6378 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006379}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006380#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006381
Guido van Rossum687dd131993-05-17 08:34:16 +00006382/* Functions acting on file descriptors */
6383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006384PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006385"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006386Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006387
Barry Warsaw53699e91996-12-10 23:23:01 +00006388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006389posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006390{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006391 char *file = NULL;
6392 int flag;
6393 int mode = 0777;
6394 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006395
6396#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006397 PyUnicodeObject *po;
6398 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6399 Py_BEGIN_ALLOW_THREADS
6400 /* PyUnicode_AS_UNICODE OK without thread
6401 lock as it is a simple dereference. */
6402 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6403 Py_END_ALLOW_THREADS
6404 if (fd < 0)
6405 return posix_error();
6406 return PyInt_FromLong((long)fd);
6407 }
6408 /* Drop the argument parsing error as narrow strings
6409 are also valid. */
6410 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006411#endif
6412
Victor Stinnerd6f85422010-05-05 23:33:33 +00006413 if (!PyArg_ParseTuple(args, "eti|i",
6414 Py_FileSystemDefaultEncoding, &file,
6415 &flag, &mode))
6416 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006417
Victor Stinnerd6f85422010-05-05 23:33:33 +00006418 Py_BEGIN_ALLOW_THREADS
6419 fd = open(file, flag, mode);
6420 Py_END_ALLOW_THREADS
6421 if (fd < 0)
6422 return posix_error_with_allocated_filename(file);
6423 PyMem_Free(file);
6424 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006425}
6426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006428PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006429"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006430Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006431
Barry Warsaw53699e91996-12-10 23:23:01 +00006432static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006433posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006434{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006435 int fd, res;
6436 if (!PyArg_ParseTuple(args, "i:close", &fd))
6437 return NULL;
6438 if (!_PyVerify_fd(fd))
6439 return posix_error();
6440 Py_BEGIN_ALLOW_THREADS
6441 res = close(fd);
6442 Py_END_ALLOW_THREADS
6443 if (res < 0)
6444 return posix_error();
6445 Py_INCREF(Py_None);
6446 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006447}
6448
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006449
Victor Stinnerd6f85422010-05-05 23:33:33 +00006450PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006451"closerange(fd_low, fd_high)\n\n\
6452Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6453
6454static PyObject *
6455posix_closerange(PyObject *self, PyObject *args)
6456{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006457 int fd_from, fd_to, i;
6458 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6459 return NULL;
6460 Py_BEGIN_ALLOW_THREADS
6461 for (i = fd_from; i < fd_to; i++)
6462 if (_PyVerify_fd(i))
6463 close(i);
6464 Py_END_ALLOW_THREADS
6465 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006466}
6467
6468
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006469PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006470"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006471Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006472
Barry Warsaw53699e91996-12-10 23:23:01 +00006473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006474posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006475{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006476 int fd;
6477 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6478 return NULL;
6479 if (!_PyVerify_fd(fd))
6480 return posix_error();
6481 Py_BEGIN_ALLOW_THREADS
6482 fd = dup(fd);
6483 Py_END_ALLOW_THREADS
6484 if (fd < 0)
6485 return posix_error();
6486 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006487}
6488
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006489
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006490PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006491"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006492Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006493
Barry Warsaw53699e91996-12-10 23:23:01 +00006494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006495posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006496{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006497 int fd, fd2, res;
6498 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6499 return NULL;
6500 if (!_PyVerify_fd_dup2(fd, fd2))
6501 return posix_error();
6502 Py_BEGIN_ALLOW_THREADS
6503 res = dup2(fd, fd2);
6504 Py_END_ALLOW_THREADS
6505 if (res < 0)
6506 return posix_error();
6507 Py_INCREF(Py_None);
6508 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006509}
6510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006511
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006512PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006513"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006515
Barry Warsaw53699e91996-12-10 23:23:01 +00006516static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006517posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006518{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006519 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006520#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006521 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006522#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006523 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006524#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006525 PyObject *posobj;
6526 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6527 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006528#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006529 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6530 switch (how) {
6531 case 0: how = SEEK_SET; break;
6532 case 1: how = SEEK_CUR; break;
6533 case 2: how = SEEK_END; break;
6534 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006535#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006536
6537#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006538 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006539#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006540 pos = PyLong_Check(posobj) ?
6541 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006542#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006543 if (PyErr_Occurred())
6544 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006545
Victor Stinnerd6f85422010-05-05 23:33:33 +00006546 if (!_PyVerify_fd(fd))
6547 return posix_error();
6548 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006549#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006550 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006551#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006552 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006553#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006554 Py_END_ALLOW_THREADS
6555 if (res < 0)
6556 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006557
6558#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006559 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006560#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006561 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006562#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006563}
6564
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006565
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006566PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006567"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006568Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006569
Barry Warsaw53699e91996-12-10 23:23:01 +00006570static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006571posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006572{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006573 int fd, size, n;
6574 PyObject *buffer;
6575 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6576 return NULL;
6577 if (size < 0) {
6578 errno = EINVAL;
6579 return posix_error();
6580 }
6581 buffer = PyString_FromStringAndSize((char *)NULL, size);
6582 if (buffer == NULL)
6583 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006584 if (!_PyVerify_fd(fd)) {
6585 Py_DECREF(buffer);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006586 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006587 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006588 Py_BEGIN_ALLOW_THREADS
6589 n = read(fd, PyString_AsString(buffer), size);
6590 Py_END_ALLOW_THREADS
6591 if (n < 0) {
6592 Py_DECREF(buffer);
6593 return posix_error();
6594 }
6595 if (n != size)
6596 _PyString_Resize(&buffer, n);
6597 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006598}
6599
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006602"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006603Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006604
Barry Warsaw53699e91996-12-10 23:23:01 +00006605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006606posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006607{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006608 Py_buffer pbuf;
6609 int fd;
6610 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006611
Victor Stinnerd6f85422010-05-05 23:33:33 +00006612 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6613 return NULL;
Stefan Krahacaab2a2010-11-26 15:06:27 +00006614 if (!_PyVerify_fd(fd)) {
6615 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006616 return posix_error();
Stefan Krahacaab2a2010-11-26 15:06:27 +00006617 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00006618 Py_BEGIN_ALLOW_THREADS
6619 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6620 Py_END_ALLOW_THREADS
Stefan Krahacaab2a2010-11-26 15:06:27 +00006621 PyBuffer_Release(&pbuf);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006622 if (size < 0)
6623 return posix_error();
6624 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006625}
6626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006628PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006629"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006630Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006631
Barry Warsaw53699e91996-12-10 23:23:01 +00006632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006633posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006634{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006635 int fd;
6636 STRUCT_STAT st;
6637 int res;
6638 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6639 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006640#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006641 /* on OpenVMS we must ensure that all bytes are written to the file */
6642 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006643#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006644 if (!_PyVerify_fd(fd))
6645 return posix_error();
6646 Py_BEGIN_ALLOW_THREADS
6647 res = FSTAT(fd, &st);
6648 Py_END_ALLOW_THREADS
6649 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006650#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006651 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006652#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006653 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006654#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006655 }
Tim Peters5aa91602002-01-30 05:46:57 +00006656
Victor Stinnerd6f85422010-05-05 23:33:33 +00006657 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006658}
6659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006662"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006664
Barry Warsaw53699e91996-12-10 23:23:01 +00006665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006666posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006667{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006668 int fd;
6669 char *orgmode = "r";
6670 int bufsize = -1;
6671 FILE *fp;
6672 PyObject *f;
6673 char *mode;
6674 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6675 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006676
Victor Stinnerd6f85422010-05-05 23:33:33 +00006677 /* Sanitize mode. See fileobject.c */
6678 mode = PyMem_MALLOC(strlen(orgmode)+3);
6679 if (!mode) {
6680 PyErr_NoMemory();
6681 return NULL;
6682 }
6683 strcpy(mode, orgmode);
6684 if (_PyFile_SanitizeMode(mode)) {
6685 PyMem_FREE(mode);
6686 return NULL;
6687 }
6688 if (!_PyVerify_fd(fd))
6689 return posix_error();
6690 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006691#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006692 if (mode[0] == 'a') {
6693 /* try to make sure the O_APPEND flag is set */
6694 int flags;
6695 flags = fcntl(fd, F_GETFL);
6696 if (flags != -1)
6697 fcntl(fd, F_SETFL, flags | O_APPEND);
6698 fp = fdopen(fd, mode);
6699 if (fp == NULL && flags != -1)
6700 /* restore old mode if fdopen failed */
6701 fcntl(fd, F_SETFL, flags);
6702 } else {
6703 fp = fdopen(fd, mode);
6704 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006705#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006706 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006707#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006708 Py_END_ALLOW_THREADS
6709 PyMem_FREE(mode);
6710 if (fp == NULL)
6711 return posix_error();
6712 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6713 if (f != NULL)
6714 PyFile_SetBufSize(f, bufsize);
6715 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006716}
6717
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006718PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006719"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006720Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006721connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006722
6723static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006724posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006725{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006726 int fd;
6727 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6728 return NULL;
6729 if (!_PyVerify_fd(fd))
6730 return PyBool_FromLong(0);
6731 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006732}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006733
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006734#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006735PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006736"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006737Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006738
Barry Warsaw53699e91996-12-10 23:23:01 +00006739static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006740posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006741{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006742#if defined(PYOS_OS2)
6743 HFILE read, write;
6744 APIRET rc;
6745
Victor Stinnerd6f85422010-05-05 23:33:33 +00006746 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006747 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006748 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006749 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006750 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006751
6752 return Py_BuildValue("(ii)", read, write);
6753#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006754#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006755 int fds[2];
6756 int res;
6757 Py_BEGIN_ALLOW_THREADS
6758 res = pipe(fds);
6759 Py_END_ALLOW_THREADS
6760 if (res != 0)
6761 return posix_error();
6762 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006763#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006764 HANDLE read, write;
6765 int read_fd, write_fd;
6766 BOOL ok;
6767 Py_BEGIN_ALLOW_THREADS
6768 ok = CreatePipe(&read, &write, NULL, 0);
6769 Py_END_ALLOW_THREADS
6770 if (!ok)
6771 return win32_error("CreatePipe", NULL);
6772 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6773 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6774 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006775#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006776#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006777}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006778#endif /* HAVE_PIPE */
6779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006780
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006781#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006782PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006783"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006784Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006785
Barry Warsaw53699e91996-12-10 23:23:01 +00006786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006787posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006788{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006789 char *filename;
6790 int mode = 0666;
6791 int res;
6792 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6793 return NULL;
6794 Py_BEGIN_ALLOW_THREADS
6795 res = mkfifo(filename, mode);
6796 Py_END_ALLOW_THREADS
6797 if (res < 0)
6798 return posix_error();
6799 Py_INCREF(Py_None);
6800 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006801}
6802#endif
6803
6804
Neal Norwitz11690112002-07-30 01:08:28 +00006805#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006806PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006807"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006808Create a filesystem node (file, device special file or named pipe)\n\
6809named filename. mode specifies both the permissions to use and the\n\
6810type of node to be created, being combined (bitwise OR) with one of\n\
6811S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006812device defines the newly created device special file (probably using\n\
6813os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006814
6815
6816static PyObject *
6817posix_mknod(PyObject *self, PyObject *args)
6818{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006819 char *filename;
6820 int mode = 0600;
6821 int device = 0;
6822 int res;
6823 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6824 return NULL;
6825 Py_BEGIN_ALLOW_THREADS
6826 res = mknod(filename, mode, device);
6827 Py_END_ALLOW_THREADS
6828 if (res < 0)
6829 return posix_error();
6830 Py_INCREF(Py_None);
6831 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006832}
6833#endif
6834
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006835#ifdef HAVE_DEVICE_MACROS
6836PyDoc_STRVAR(posix_major__doc__,
6837"major(device) -> major number\n\
6838Extracts a device major number from a raw device number.");
6839
6840static PyObject *
6841posix_major(PyObject *self, PyObject *args)
6842{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006843 int device;
6844 if (!PyArg_ParseTuple(args, "i:major", &device))
6845 return NULL;
6846 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006847}
6848
6849PyDoc_STRVAR(posix_minor__doc__,
6850"minor(device) -> minor number\n\
6851Extracts a device minor number from a raw device number.");
6852
6853static PyObject *
6854posix_minor(PyObject *self, PyObject *args)
6855{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006856 int device;
6857 if (!PyArg_ParseTuple(args, "i:minor", &device))
6858 return NULL;
6859 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006860}
6861
6862PyDoc_STRVAR(posix_makedev__doc__,
6863"makedev(major, minor) -> device number\n\
6864Composes a raw device number from the major and minor device numbers.");
6865
6866static PyObject *
6867posix_makedev(PyObject *self, PyObject *args)
6868{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006869 int major, minor;
6870 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6871 return NULL;
6872 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006873}
6874#endif /* device macros */
6875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006876
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006877#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006878PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006879"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006880Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006881
Barry Warsaw53699e91996-12-10 23:23:01 +00006882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006883posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006884{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006885 int fd;
6886 off_t length;
6887 int res;
6888 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006889
Victor Stinnerd6f85422010-05-05 23:33:33 +00006890 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6891 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006892
6893#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006894 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006895#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006896 length = PyLong_Check(lenobj) ?
6897 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006898#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006899 if (PyErr_Occurred())
6900 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006901
Victor Stinnerd6f85422010-05-05 23:33:33 +00006902 Py_BEGIN_ALLOW_THREADS
6903 res = ftruncate(fd, length);
6904 Py_END_ALLOW_THREADS
6905 if (res < 0)
6906 return posix_error();
6907 Py_INCREF(Py_None);
6908 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006909}
6910#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006911
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006912#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006913PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006914"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006915Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006916
Fred Drake762e2061999-08-26 17:23:54 +00006917/* Save putenv() parameters as values here, so we can collect them when they
6918 * get re-set with another call for the same key. */
6919static PyObject *posix_putenv_garbage;
6920
Tim Peters5aa91602002-01-30 05:46:57 +00006921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006922posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006923{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006924 char *s1, *s2;
6925 char *newenv;
6926 PyObject *newstr;
6927 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006928
Victor Stinnerd6f85422010-05-05 23:33:33 +00006929 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6930 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006931
6932#if defined(PYOS_OS2)
6933 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6934 APIRET rc;
6935
Guido van Rossumd48f2521997-12-05 22:19:34 +00006936 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6937 if (rc != NO_ERROR)
6938 return os2_error(rc);
6939
6940 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6941 APIRET rc;
6942
Guido van Rossumd48f2521997-12-05 22:19:34 +00006943 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6944 if (rc != NO_ERROR)
6945 return os2_error(rc);
6946 } else {
6947#endif
6948
Victor Stinnerd6f85422010-05-05 23:33:33 +00006949 /* XXX This can leak memory -- not easy to fix :-( */
6950 len = strlen(s1) + strlen(s2) + 2;
6951 /* len includes space for a trailing \0; the size arg to
6952 PyString_FromStringAndSize does not count that */
6953 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6954 if (newstr == NULL)
6955 return PyErr_NoMemory();
6956 newenv = PyString_AS_STRING(newstr);
6957 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6958 if (putenv(newenv)) {
6959 Py_DECREF(newstr);
6960 posix_error();
6961 return NULL;
6962 }
6963 /* Install the first arg and newstr in posix_putenv_garbage;
6964 * this will cause previous value to be collected. This has to
6965 * happen after the real putenv() call because the old value
6966 * was still accessible until then. */
6967 if (PyDict_SetItem(posix_putenv_garbage,
6968 PyTuple_GET_ITEM(args, 0), newstr)) {
6969 /* really not much we can do; just leak */
6970 PyErr_Clear();
6971 }
6972 else {
6973 Py_DECREF(newstr);
6974 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006975
6976#if defined(PYOS_OS2)
6977 }
6978#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006979 Py_INCREF(Py_None);
6980 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006981}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006982#endif /* putenv */
6983
Guido van Rossumc524d952001-10-19 01:31:59 +00006984#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006985PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006986"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006987Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006988
6989static PyObject *
6990posix_unsetenv(PyObject *self, PyObject *args)
6991{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006992 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006993
Victor Stinnerd6f85422010-05-05 23:33:33 +00006994 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6995 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00006996
Victor Stinnerd6f85422010-05-05 23:33:33 +00006997 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006998
Victor Stinnerd6f85422010-05-05 23:33:33 +00006999 /* Remove the key from posix_putenv_garbage;
7000 * this will cause it to be collected. This has to
7001 * happen after the real unsetenv() call because the
7002 * old value was still accessible until then.
7003 */
7004 if (PyDict_DelItem(posix_putenv_garbage,
7005 PyTuple_GET_ITEM(args, 0))) {
7006 /* really not much we can do; just leak */
7007 PyErr_Clear();
7008 }
Guido van Rossumc524d952001-10-19 01:31:59 +00007009
Victor Stinnerd6f85422010-05-05 23:33:33 +00007010 Py_INCREF(Py_None);
7011 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00007012}
7013#endif /* unsetenv */
7014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007015PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007016"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007017Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00007018
Guido van Rossumf68d8e52001-04-14 17:55:09 +00007019static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007020posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00007021{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007022 int code;
7023 char *message;
7024 if (!PyArg_ParseTuple(args, "i:strerror", &code))
7025 return NULL;
7026 message = strerror(code);
7027 if (message == NULL) {
7028 PyErr_SetString(PyExc_ValueError,
7029 "strerror() argument out of range");
7030 return NULL;
7031 }
7032 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00007033}
Guido van Rossumb6a47161997-09-15 22:54:34 +00007034
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007035
Guido van Rossumc9641791998-08-04 15:26:23 +00007036#ifdef HAVE_SYS_WAIT_H
7037
Fred Drake106c1a02002-04-23 15:58:02 +00007038#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007039PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007040"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007041Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00007042
7043static PyObject *
7044posix_WCOREDUMP(PyObject *self, PyObject *args)
7045{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007046 WAIT_TYPE status;
7047 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007048
Victor Stinnerd6f85422010-05-05 23:33:33 +00007049 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
7050 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007051
Victor Stinnerd6f85422010-05-05 23:33:33 +00007052 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007053}
7054#endif /* WCOREDUMP */
7055
7056#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007057PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007058"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007059Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007060job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007061
7062static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007063posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007064{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007065 WAIT_TYPE status;
7066 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007067
Victor Stinnerd6f85422010-05-05 23:33:33 +00007068 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7069 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007070
Victor Stinnerd6f85422010-05-05 23:33:33 +00007071 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007072}
7073#endif /* WIFCONTINUED */
7074
Guido van Rossumc9641791998-08-04 15:26:23 +00007075#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007077"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007078Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007079
7080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007081posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007082{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007083 WAIT_TYPE status;
7084 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007085
Victor Stinnerd6f85422010-05-05 23:33:33 +00007086 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7087 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007088
Victor Stinnerd6f85422010-05-05 23:33:33 +00007089 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007090}
7091#endif /* WIFSTOPPED */
7092
7093#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007094PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007095"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007096Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007097
7098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007099posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007100{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007101 WAIT_TYPE status;
7102 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007103
Victor Stinnerd6f85422010-05-05 23:33:33 +00007104 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7105 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007106
Victor Stinnerd6f85422010-05-05 23:33:33 +00007107 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007108}
7109#endif /* WIFSIGNALED */
7110
7111#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007112PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007113"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007114Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007115system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007116
7117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007118posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007119{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007120 WAIT_TYPE status;
7121 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007122
Victor Stinnerd6f85422010-05-05 23:33:33 +00007123 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7124 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007125
Victor Stinnerd6f85422010-05-05 23:33:33 +00007126 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007127}
7128#endif /* WIFEXITED */
7129
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007130#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007131PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007132"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007133Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007134
7135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007136posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007137{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007138 WAIT_TYPE status;
7139 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007140
Victor Stinnerd6f85422010-05-05 23:33:33 +00007141 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7142 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007143
Victor Stinnerd6f85422010-05-05 23:33:33 +00007144 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007145}
7146#endif /* WEXITSTATUS */
7147
7148#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007149PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007150"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007151Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007152value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007153
7154static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007155posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007156{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007157 WAIT_TYPE status;
7158 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007159
Victor Stinnerd6f85422010-05-05 23:33:33 +00007160 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7161 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007162
Victor Stinnerd6f85422010-05-05 23:33:33 +00007163 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007164}
7165#endif /* WTERMSIG */
7166
7167#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007168PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007169"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007170Return the signal that stopped the process that provided\n\
7171the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007172
7173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007174posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007175{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007176 WAIT_TYPE status;
7177 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007178
Victor Stinnerd6f85422010-05-05 23:33:33 +00007179 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007181
Victor Stinnerd6f85422010-05-05 23:33:33 +00007182 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007183}
7184#endif /* WSTOPSIG */
7185
7186#endif /* HAVE_SYS_WAIT_H */
7187
7188
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007189#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007190#ifdef _SCO_DS
7191/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7192 needed definitions in sys/statvfs.h */
7193#define _SVID3
7194#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007195#include <sys/statvfs.h>
7196
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007197static PyObject*
7198_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007199 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7200 if (v == NULL)
7201 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007202
7203#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007204 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7205 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7206 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7207 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7208 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7209 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7210 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7211 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7212 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7213 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007214#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007215 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7216 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7217 PyStructSequence_SET_ITEM(v, 2,
7218 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7219 PyStructSequence_SET_ITEM(v, 3,
7220 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7221 PyStructSequence_SET_ITEM(v, 4,
7222 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7223 PyStructSequence_SET_ITEM(v, 5,
7224 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7225 PyStructSequence_SET_ITEM(v, 6,
7226 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7227 PyStructSequence_SET_ITEM(v, 7,
7228 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7229 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7230 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007231#endif
7232
Victor Stinnerd6f85422010-05-05 23:33:33 +00007233 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007234}
7235
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007236PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007237"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007238Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007239
7240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007241posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007242{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007243 int fd, res;
7244 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007245
Victor Stinnerd6f85422010-05-05 23:33:33 +00007246 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7247 return NULL;
7248 Py_BEGIN_ALLOW_THREADS
7249 res = fstatvfs(fd, &st);
7250 Py_END_ALLOW_THREADS
7251 if (res != 0)
7252 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007253
Victor Stinnerd6f85422010-05-05 23:33:33 +00007254 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007255}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007256#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007257
7258
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007259#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007260#include <sys/statvfs.h>
7261
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007262PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007263"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007264Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007265
7266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007267posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007268{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007269 char *path;
7270 int res;
7271 struct statvfs st;
7272 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7273 return NULL;
7274 Py_BEGIN_ALLOW_THREADS
7275 res = statvfs(path, &st);
7276 Py_END_ALLOW_THREADS
7277 if (res != 0)
7278 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007279
Victor Stinnerd6f85422010-05-05 23:33:33 +00007280 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007281}
7282#endif /* HAVE_STATVFS */
7283
7284
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007285#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007286PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007287"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007288Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007289The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007290or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007291
7292static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007293posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007294{
7295 PyObject *result = NULL;
7296 char *dir = NULL;
7297 char *pfx = NULL;
7298 char *name;
7299
7300 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007301 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007302
7303 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007304 "tempnam is a potential security risk to your program") < 0)
7305 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007306
Antoine Pitroub0614612011-01-02 20:04:52 +00007307 if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
7308 "use the tempfile module", 1) < 0)
7309 return NULL;
7310
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007311#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007312 name = _tempnam(dir, pfx);
7313#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007314 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007315#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007316 if (name == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007317 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007318 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007319 free(name);
7320 return result;
7321}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007322#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007323
7324
7325#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007326PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007327"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007328Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007329
7330static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007331posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007332{
7333 FILE *fp;
7334
Antoine Pitroub0614612011-01-02 20:04:52 +00007335 if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
7336 "use the tempfile module", 1) < 0)
7337 return NULL;
7338
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007339 fp = tmpfile();
7340 if (fp == NULL)
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007341 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007342 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007343}
7344#endif
7345
7346
7347#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007348PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007349"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007350Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007351
7352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007353posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007354{
7355 char buffer[L_tmpnam];
7356 char *name;
7357
Skip Montanaro95618b52001-08-18 18:52:10 +00007358 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007359 "tmpnam is a potential security risk to your program") < 0)
7360 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007361
Antoine Pitroub0614612011-01-02 20:04:52 +00007362 if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
7363 "use the tempfile module", 1) < 0)
7364 return NULL;
7365
Greg Wardb48bc172000-03-01 21:51:56 +00007366#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367 name = tmpnam_r(buffer);
7368#else
7369 name = tmpnam(buffer);
7370#endif
7371 if (name == NULL) {
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007372 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007373#ifdef USE_TMPNAM_R
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007374 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007375#else
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007376 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007377#endif
Antoine Pitrouda4a5f02011-01-02 20:06:12 +00007378 );
7379 PyErr_SetObject(PyExc_OSError, err);
7380 Py_XDECREF(err);
7381 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007382 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007383 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007384}
7385#endif
7386
7387
Fred Drakec9680921999-12-13 16:37:25 +00007388/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7389 * It maps strings representing configuration variable names to
7390 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007391 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007392 * rarely-used constants. There are three separate tables that use
7393 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007394 *
7395 * This code is always included, even if none of the interfaces that
7396 * need it are included. The #if hackery needed to avoid it would be
7397 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007398 */
7399struct constdef {
7400 char *name;
7401 long value;
7402};
7403
Fred Drake12c6e2d1999-12-14 21:25:03 +00007404static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007405conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007406 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007407{
7408 if (PyInt_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007409 *valuep = PyInt_AS_LONG(arg);
7410 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007411 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007412 if (PyString_Check(arg)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007413 /* look up the value in the table using a binary search */
7414 size_t lo = 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00007415 size_t mid;
Stefan Krah93f7a322010-11-26 17:35:50 +00007416 size_t hi = tablesize;
7417 int cmp;
7418 char *confname = PyString_AS_STRING(arg);
7419 while (lo < hi) {
7420 mid = (lo + hi) / 2;
7421 cmp = strcmp(confname, table[mid].name);
7422 if (cmp < 0)
7423 hi = mid;
7424 else if (cmp > 0)
7425 lo = mid + 1;
7426 else {
7427 *valuep = table[mid].value;
7428 return 1;
7429 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00007430 }
Stefan Krah93f7a322010-11-26 17:35:50 +00007431 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007432 }
7433 else
Stefan Krah93f7a322010-11-26 17:35:50 +00007434 PyErr_SetString(PyExc_TypeError,
7435 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007436 return 0;
7437}
7438
7439
7440#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7441static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007442#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007443 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007444#endif
7445#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007446 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007447#endif
Fred Drakec9680921999-12-13 16:37:25 +00007448#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007449 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007450#endif
7451#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007452 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007453#endif
7454#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007455 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007456#endif
7457#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007458 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007459#endif
7460#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007461 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007462#endif
7463#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007464 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007465#endif
7466#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007467 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007468#endif
7469#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007470 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007471#endif
7472#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007473 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007474#endif
7475#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007476 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007477#endif
7478#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007479 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007480#endif
7481#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007482 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007483#endif
7484#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007485 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007486#endif
7487#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007488 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007489#endif
7490#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007491 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007492#endif
7493};
7494
Fred Drakec9680921999-12-13 16:37:25 +00007495static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007496conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007497{
7498 return conv_confname(arg, valuep, posix_constants_pathconf,
7499 sizeof(posix_constants_pathconf)
7500 / sizeof(struct constdef));
7501}
7502#endif
7503
7504#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007505PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007506"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007507Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007508If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007509
7510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007511posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007512{
7513 PyObject *result = NULL;
7514 int name, fd;
7515
Fred Drake12c6e2d1999-12-14 21:25:03 +00007516 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7517 conv_path_confname, &name)) {
Stefan Krah93f7a322010-11-26 17:35:50 +00007518 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007519
Stefan Krah93f7a322010-11-26 17:35:50 +00007520 errno = 0;
7521 limit = fpathconf(fd, name);
7522 if (limit == -1 && errno != 0)
7523 posix_error();
7524 else
7525 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007526 }
7527 return result;
7528}
7529#endif
7530
7531
7532#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007533PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007534"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007535Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007536If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007537
7538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007539posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007540{
7541 PyObject *result = NULL;
7542 int name;
7543 char *path;
7544
7545 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7546 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007547 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007548
Victor Stinnerd6f85422010-05-05 23:33:33 +00007549 errno = 0;
7550 limit = pathconf(path, name);
7551 if (limit == -1 && errno != 0) {
7552 if (errno == EINVAL)
Stefan Krahacaab2a2010-11-26 15:06:27 +00007553 /* could be a path or name problem */
7554 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007555 else
Stefan Krahacaab2a2010-11-26 15:06:27 +00007556 posix_error_with_filename(path);
Victor Stinnerd6f85422010-05-05 23:33:33 +00007557 }
7558 else
7559 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007560 }
7561 return result;
7562}
7563#endif
7564
7565#ifdef HAVE_CONFSTR
7566static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007567#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007568 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007569#endif
7570#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007571 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007572#endif
7573#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007574 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007575#endif
7576#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007577 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007578#endif
7579#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007580 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007581#endif
Fred Drakec9680921999-12-13 16:37:25 +00007582#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007583 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007584#endif
7585#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007586 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007587#endif
7588#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007589 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007590#endif
7591#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007592 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007593#endif
7594#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007595 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007596#endif
7597#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007598 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007599#endif
7600#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007601 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007602#endif
7603#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007604 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007605#endif
Fred Draked86ed291999-12-15 15:34:33 +00007606#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007607 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007608#endif
Fred Drakec9680921999-12-13 16:37:25 +00007609#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007610 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007611#endif
Fred Draked86ed291999-12-15 15:34:33 +00007612#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007613 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007614#endif
7615#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007616 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007617#endif
7618#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007619 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007620#endif
7621#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007622 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007623#endif
Fred Drakec9680921999-12-13 16:37:25 +00007624#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007625 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007626#endif
7627#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007628 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007629#endif
7630#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007631 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007632#endif
7633#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007634 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007635#endif
7636#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007637 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007638#endif
7639#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007640 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007641#endif
7642#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007643 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007644#endif
7645#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007646 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007647#endif
7648#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007649 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007650#endif
7651#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007652 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007653#endif
7654#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007655 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007656#endif
7657#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007658 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007659#endif
7660#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007661 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007662#endif
7663#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007664 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007665#endif
7666#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007667 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007668#endif
7669#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007670 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007671#endif
Fred Draked86ed291999-12-15 15:34:33 +00007672#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007673 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007674#endif
7675#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007676 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007677#endif
7678#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007679 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007680#endif
7681#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007682 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007683#endif
7684#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007685 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007686#endif
7687#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007688 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007689#endif
7690#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007691 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007692#endif
7693#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007694 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007695#endif
7696#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007697 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007698#endif
7699#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007700 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007701#endif
7702#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007703 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007704#endif
7705#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007706 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007707#endif
7708#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007709 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007710#endif
Fred Drakec9680921999-12-13 16:37:25 +00007711};
7712
7713static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007714conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007715{
7716 return conv_confname(arg, valuep, posix_constants_confstr,
7717 sizeof(posix_constants_confstr)
7718 / sizeof(struct constdef));
7719}
7720
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007721PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007722"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007723Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007724
7725static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007726posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007727{
7728 PyObject *result = NULL;
7729 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007730 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007731
7732 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007733 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007734
Victor Stinnerd6f85422010-05-05 23:33:33 +00007735 errno = 0;
7736 len = confstr(name, buffer, sizeof(buffer));
7737 if (len == 0) {
7738 if (errno) {
7739 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007740 }
7741 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007742 result = Py_None;
7743 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007744 }
7745 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007746 else {
7747 if ((unsigned int)len >= sizeof(buffer)) {
7748 result = PyString_FromStringAndSize(NULL, len-1);
7749 if (result != NULL)
7750 confstr(name, PyString_AS_STRING(result), len);
7751 }
7752 else
7753 result = PyString_FromStringAndSize(buffer, len-1);
7754 }
7755 }
Fred Drakec9680921999-12-13 16:37:25 +00007756 return result;
7757}
7758#endif
7759
7760
7761#ifdef HAVE_SYSCONF
7762static struct constdef posix_constants_sysconf[] = {
7763#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007764 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007765#endif
7766#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007767 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007768#endif
7769#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007770 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007771#endif
7772#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007773 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007774#endif
7775#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007776 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007777#endif
7778#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007779 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007780#endif
7781#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007782 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007783#endif
7784#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007785 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007786#endif
7787#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007788 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007789#endif
7790#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007791 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007792#endif
Fred Draked86ed291999-12-15 15:34:33 +00007793#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007794 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007795#endif
7796#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007797 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007798#endif
Fred Drakec9680921999-12-13 16:37:25 +00007799#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007800 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007801#endif
Fred Drakec9680921999-12-13 16:37:25 +00007802#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007803 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007804#endif
7805#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007806 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007807#endif
7808#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007809 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007810#endif
7811#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007812 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007813#endif
7814#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007815 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007816#endif
Fred Draked86ed291999-12-15 15:34:33 +00007817#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007818 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007819#endif
Fred Drakec9680921999-12-13 16:37:25 +00007820#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007821 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007822#endif
7823#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007824 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007825#endif
7826#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007827 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007828#endif
7829#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007830 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007831#endif
7832#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007833 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007834#endif
Fred Draked86ed291999-12-15 15:34:33 +00007835#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007836 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007837#endif
Fred Drakec9680921999-12-13 16:37:25 +00007838#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007839 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007840#endif
7841#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007842 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007843#endif
7844#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007845 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007846#endif
7847#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007848 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007849#endif
7850#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007851 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007852#endif
7853#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007854 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007855#endif
7856#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007857 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007858#endif
7859#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007860 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007861#endif
7862#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007863 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007864#endif
7865#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007866 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007867#endif
7868#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007869 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007870#endif
7871#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007872 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007873#endif
7874#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007875 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007876#endif
7877#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007878 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007879#endif
7880#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007881 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007882#endif
7883#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007884 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007885#endif
7886#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007887 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007888#endif
7889#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007890 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007891#endif
7892#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007893 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007894#endif
7895#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007896 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007897#endif
7898#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007899 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007900#endif
7901#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007902 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007903#endif
7904#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007905 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007906#endif
Fred Draked86ed291999-12-15 15:34:33 +00007907#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007908 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007909#endif
Fred Drakec9680921999-12-13 16:37:25 +00007910#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007911 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007912#endif
7913#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007914 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007915#endif
7916#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007917 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007918#endif
Fred Draked86ed291999-12-15 15:34:33 +00007919#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007920 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007921#endif
Fred Drakec9680921999-12-13 16:37:25 +00007922#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007923 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007924#endif
Fred Draked86ed291999-12-15 15:34:33 +00007925#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007926 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007927#endif
7928#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007929 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007930#endif
Fred Drakec9680921999-12-13 16:37:25 +00007931#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007932 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007933#endif
7934#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007935 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007936#endif
7937#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007938 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007939#endif
7940#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007941 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007942#endif
Fred Draked86ed291999-12-15 15:34:33 +00007943#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007944 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007945#endif
Fred Drakec9680921999-12-13 16:37:25 +00007946#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007947 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007948#endif
7949#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007950 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007951#endif
7952#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007953 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007954#endif
7955#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007956 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007957#endif
7958#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007959 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007960#endif
7961#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007962 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007963#endif
7964#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00007965 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007966#endif
Fred Draked86ed291999-12-15 15:34:33 +00007967#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007968 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007969#endif
Fred Drakec9680921999-12-13 16:37:25 +00007970#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007971 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007972#endif
7973#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007974 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007975#endif
Fred Draked86ed291999-12-15 15:34:33 +00007976#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007977 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007978#endif
Fred Drakec9680921999-12-13 16:37:25 +00007979#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007980 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007981#endif
7982#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007983 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007984#endif
7985#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007986 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007987#endif
7988#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007989 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007990#endif
7991#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007992 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007993#endif
7994#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007995 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007996#endif
7997#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007998 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007999#endif
8000#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008001 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00008002#endif
8003#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008004 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00008005#endif
Fred Draked86ed291999-12-15 15:34:33 +00008006#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008007 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00008008#endif
8009#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008010 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00008011#endif
Fred Drakec9680921999-12-13 16:37:25 +00008012#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008013 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00008014#endif
8015#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008016 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008017#endif
8018#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008019 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008020#endif
8021#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008022 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008023#endif
8024#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008025 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008026#endif
8027#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008028 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00008029#endif
8030#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00008031 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00008032#endif
8033#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008034 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00008035#endif
8036#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008037 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00008038#endif
8039#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008040 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00008041#endif
8042#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008043 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00008044#endif
8045#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008046 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00008047#endif
8048#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008049 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00008050#endif
8051#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00008052 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00008053#endif
8054#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00008055 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00008056#endif
8057#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00008058 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00008059#endif
8060#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008061 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00008062#endif
8063#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008064 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008065#endif
8066#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008067 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008068#endif
8069#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008070 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008071#endif
8072#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008073 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008074#endif
8075#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008076 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008077#endif
8078#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008079 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008080#endif
8081#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008082 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008083#endif
8084#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008085 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008086#endif
8087#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008088 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008089#endif
8090#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008091 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008092#endif
8093#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008094 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008095#endif
8096#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008097 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008098#endif
8099#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008100 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008101#endif
8102#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008103 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008104#endif
8105#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008106 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008107#endif
8108#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008109 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008110#endif
8111#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008112 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008113#endif
8114#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008115 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008116#endif
Fred Draked86ed291999-12-15 15:34:33 +00008117#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008118 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008119#endif
Fred Drakec9680921999-12-13 16:37:25 +00008120#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008121 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008122#endif
8123#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008124 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008125#endif
8126#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008127 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008128#endif
8129#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008130 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008131#endif
8132#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008133 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008134#endif
8135#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008136 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008137#endif
8138#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008139 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008140#endif
8141#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008142 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008143#endif
8144#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008145 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008146#endif
8147#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008148 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008149#endif
8150#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008151 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008152#endif
8153#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008154 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008155#endif
8156#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008157 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008158#endif
8159#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008160 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008161#endif
8162#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008163 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008164#endif
8165#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008166 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008167#endif
8168#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008169 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008170#endif
8171#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008172 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008173#endif
8174#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008175 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008176#endif
8177#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008178 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008179#endif
8180#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008181 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008182#endif
8183#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008184 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008185#endif
8186#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008187 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008188#endif
8189#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008190 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008191#endif
8192#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008193 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008194#endif
8195#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008196 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008197#endif
8198#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008199 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008200#endif
8201#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008202 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008203#endif
8204#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008205 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008206#endif
8207#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008208 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008209#endif
8210#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008211 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008212#endif
8213#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008214 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008215#endif
8216#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008217 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008218#endif
8219#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008220 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008221#endif
8222#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008223 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008224#endif
8225#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008226 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008227#endif
8228#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008229 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008230#endif
8231#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008232 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008233#endif
8234#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008235 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008236#endif
8237#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008238 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008239#endif
8240#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008241 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008242#endif
8243#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008244 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008245#endif
8246#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008247 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008248#endif
8249#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008250 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008251#endif
8252#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008253 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008254#endif
8255};
8256
8257static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008258conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008259{
8260 return conv_confname(arg, valuep, posix_constants_sysconf,
8261 sizeof(posix_constants_sysconf)
8262 / sizeof(struct constdef));
8263}
8264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008265PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008266"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008267Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008268
8269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008270posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008271{
8272 PyObject *result = NULL;
8273 int name;
8274
8275 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008276 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008277
Victor Stinner862490a2010-05-06 00:03:44 +00008278 errno = 0;
8279 value = sysconf(name);
8280 if (value == -1 && errno != 0)
8281 posix_error();
8282 else
8283 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008284 }
8285 return result;
8286}
8287#endif
8288
8289
Fred Drakebec628d1999-12-15 18:31:10 +00008290/* This code is used to ensure that the tables of configuration value names
8291 * are in sorted order as required by conv_confname(), and also to build the
8292 * the exported dictionaries that are used to publish information about the
8293 * names available on the host platform.
8294 *
8295 * Sorting the table at runtime ensures that the table is properly ordered
8296 * when used, even for platforms we're not able to test on. It also makes
8297 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008298 */
Fred Drakebec628d1999-12-15 18:31:10 +00008299
8300static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008301cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008302{
8303 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008304 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008305 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008306 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008307
8308 return strcmp(c1->name, c2->name);
8309}
8310
8311static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008312setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008313 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008314{
Fred Drakebec628d1999-12-15 18:31:10 +00008315 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008316 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008317
8318 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8319 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008320 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008321 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008322
Barry Warsaw3155db32000-04-13 15:20:40 +00008323 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008324 PyObject *o = PyInt_FromLong(table[i].value);
8325 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8326 Py_XDECREF(o);
8327 Py_DECREF(d);
8328 return -1;
8329 }
8330 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008331 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008332 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008333}
8334
Fred Drakebec628d1999-12-15 18:31:10 +00008335/* Return -1 on failure, 0 on success. */
8336static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008337setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008338{
8339#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008340 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008341 sizeof(posix_constants_pathconf)
8342 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008343 "pathconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008344 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008345#endif
8346#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008347 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008348 sizeof(posix_constants_confstr)
8349 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008350 "confstr_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008351 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008352#endif
8353#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008354 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008355 sizeof(posix_constants_sysconf)
8356 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008357 "sysconf_names", module))
Stefan Krah93f7a322010-11-26 17:35:50 +00008358 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008359#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008360 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008361}
Fred Draked86ed291999-12-15 15:34:33 +00008362
8363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008364PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008365"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008366Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008367in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008368
8369static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008370posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008371{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008372 abort();
8373 /*NOTREACHED*/
8374 Py_FatalError("abort() called from Python code didn't abort!");
8375 return NULL;
8376}
Fred Drakebec628d1999-12-15 18:31:10 +00008377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008378#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008379PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008380"startfile(filepath [, operation]) - Start a file with its associated\n\
8381application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008382\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008383When \"operation\" is not specified or \"open\", this acts like\n\
8384double-clicking the file in Explorer, or giving the file name as an\n\
8385argument to the DOS \"start\" command: the file is opened with whatever\n\
8386application (if any) its extension is associated.\n\
8387When another \"operation\" is given, it specifies what should be done with\n\
8388the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008389\n\
8390startfile returns as soon as the associated application is launched.\n\
8391There is no option to wait for the application to close, and no way\n\
8392to retrieve the application's exit status.\n\
8393\n\
8394The filepath is relative to the current directory. If you want to use\n\
8395an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008396the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008397
8398static PyObject *
8399win32_startfile(PyObject *self, PyObject *args)
8400{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008401 char *filepath;
8402 char *operation = NULL;
8403 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008404
Victor Stinnerd6f85422010-05-05 23:33:33 +00008405 PyObject *unipath, *woperation = NULL;
8406 if (!PyArg_ParseTuple(args, "U|s:startfile",
8407 &unipath, &operation)) {
8408 PyErr_Clear();
8409 goto normal;
8410 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008411
Victor Stinnerd6f85422010-05-05 23:33:33 +00008412 if (operation) {
8413 woperation = PyUnicode_DecodeASCII(operation,
8414 strlen(operation), NULL);
8415 if (!woperation) {
8416 PyErr_Clear();
8417 operation = NULL;
8418 goto normal;
8419 }
8420 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008421
Victor Stinnerd6f85422010-05-05 23:33:33 +00008422 Py_BEGIN_ALLOW_THREADS
8423 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8424 PyUnicode_AS_UNICODE(unipath),
8425 NULL, NULL, SW_SHOWNORMAL);
8426 Py_END_ALLOW_THREADS
8427
8428 Py_XDECREF(woperation);
8429 if (rc <= (HINSTANCE)32) {
8430 PyObject *errval = win32_error_unicode("startfile",
8431 PyUnicode_AS_UNICODE(unipath));
8432 return errval;
8433 }
8434 Py_INCREF(Py_None);
8435 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008436
8437normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008438 if (!PyArg_ParseTuple(args, "et|s:startfile",
8439 Py_FileSystemDefaultEncoding, &filepath,
8440 &operation))
8441 return NULL;
8442 Py_BEGIN_ALLOW_THREADS
8443 rc = ShellExecute((HWND)0, operation, filepath,
8444 NULL, NULL, SW_SHOWNORMAL);
8445 Py_END_ALLOW_THREADS
8446 if (rc <= (HINSTANCE)32) {
8447 PyObject *errval = win32_error("startfile", filepath);
8448 PyMem_Free(filepath);
8449 return errval;
8450 }
8451 PyMem_Free(filepath);
8452 Py_INCREF(Py_None);
8453 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008454}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008455#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008456
Martin v. Löwis438b5342002-12-27 10:16:42 +00008457#ifdef HAVE_GETLOADAVG
8458PyDoc_STRVAR(posix_getloadavg__doc__,
8459"getloadavg() -> (float, float, float)\n\n\
8460Return the number of processes in the system run queue averaged over\n\
8461the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8462was unobtainable");
8463
8464static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008465posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008466{
8467 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008468 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah93f7a322010-11-26 17:35:50 +00008469 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8470 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008471 } else
Stefan Krah93f7a322010-11-26 17:35:50 +00008472 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008473}
8474#endif
8475
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008476#ifdef MS_WINDOWS
8477
8478PyDoc_STRVAR(win32_urandom__doc__,
8479"urandom(n) -> str\n\n\
8480Return a string of n random bytes suitable for cryptographic use.");
8481
8482typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8483 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8484 DWORD dwFlags );
8485typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8486 BYTE *pbBuffer );
8487
8488static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008489/* This handle is never explicitly released. Instead, the operating
8490 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008491static HCRYPTPROV hCryptProv = 0;
8492
Tim Peters4ad82172004-08-30 17:02:04 +00008493static PyObject*
8494win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008495{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008496 int howMany;
8497 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008498
Victor Stinnerd6f85422010-05-05 23:33:33 +00008499 /* Read arguments */
8500 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8501 return NULL;
8502 if (howMany < 0)
8503 return PyErr_Format(PyExc_ValueError,
8504 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008505
Victor Stinnerd6f85422010-05-05 23:33:33 +00008506 if (hCryptProv == 0) {
8507 HINSTANCE hAdvAPI32 = NULL;
8508 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008509
Victor Stinnerd6f85422010-05-05 23:33:33 +00008510 /* Obtain handle to the DLL containing CryptoAPI
8511 This should not fail */
8512 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8513 if(hAdvAPI32 == NULL)
8514 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008515
Victor Stinnerd6f85422010-05-05 23:33:33 +00008516 /* Obtain pointers to the CryptoAPI functions
8517 This will fail on some early versions of Win95 */
8518 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8519 hAdvAPI32,
8520 "CryptAcquireContextA");
8521 if (pCryptAcquireContext == NULL)
8522 return PyErr_Format(PyExc_NotImplementedError,
8523 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008524
Victor Stinnerd6f85422010-05-05 23:33:33 +00008525 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8526 hAdvAPI32, "CryptGenRandom");
8527 if (pCryptGenRandom == NULL)
8528 return PyErr_Format(PyExc_NotImplementedError,
8529 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008530
Victor Stinnerd6f85422010-05-05 23:33:33 +00008531 /* Acquire context */
8532 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8533 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8534 return win32_error("CryptAcquireContext", NULL);
8535 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008536
Victor Stinnerd6f85422010-05-05 23:33:33 +00008537 /* Allocate bytes */
8538 result = PyString_FromStringAndSize(NULL, howMany);
8539 if (result != NULL) {
8540 /* Get random data */
8541 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8542 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8543 PyString_AS_STRING(result))) {
8544 Py_DECREF(result);
8545 return win32_error("CryptGenRandom", NULL);
8546 }
8547 }
8548 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008549}
8550#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008551
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008552#ifdef __VMS
8553/* Use openssl random routine */
8554#include <openssl/rand.h>
8555PyDoc_STRVAR(vms_urandom__doc__,
8556"urandom(n) -> str\n\n\
8557Return a string of n random bytes suitable for cryptographic use.");
8558
8559static PyObject*
8560vms_urandom(PyObject *self, PyObject *args)
8561{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008562 int howMany;
8563 PyObject* result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008564
Victor Stinnerd6f85422010-05-05 23:33:33 +00008565 /* Read arguments */
8566 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8567 return NULL;
8568 if (howMany < 0)
8569 return PyErr_Format(PyExc_ValueError,
8570 "negative argument not allowed");
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008571
Victor Stinnerd6f85422010-05-05 23:33:33 +00008572 /* Allocate bytes */
8573 result = PyString_FromStringAndSize(NULL, howMany);
8574 if (result != NULL) {
8575 /* Get random data */
8576 if (RAND_pseudo_bytes((unsigned char*)
8577 PyString_AS_STRING(result),
8578 howMany) < 0) {
8579 Py_DECREF(result);
8580 return PyErr_Format(PyExc_ValueError,
8581 "RAND_pseudo_bytes");
8582 }
8583 }
8584 return result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008585}
8586#endif
8587
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008588#ifdef HAVE_SETRESUID
8589PyDoc_STRVAR(posix_setresuid__doc__,
8590"setresuid(ruid, euid, suid)\n\n\
8591Set the current process's real, effective, and saved user ids.");
8592
8593static PyObject*
8594posix_setresuid (PyObject *self, PyObject *args)
8595{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008596 /* We assume uid_t is no larger than a long. */
8597 long ruid, euid, suid;
8598 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8599 return NULL;
8600 if (setresuid(ruid, euid, suid) < 0)
8601 return posix_error();
8602 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008603}
8604#endif
8605
8606#ifdef HAVE_SETRESGID
8607PyDoc_STRVAR(posix_setresgid__doc__,
8608"setresgid(rgid, egid, sgid)\n\n\
8609Set the current process's real, effective, and saved group ids.");
8610
8611static PyObject*
8612posix_setresgid (PyObject *self, PyObject *args)
8613{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008614 /* We assume uid_t is no larger than a long. */
8615 long rgid, egid, sgid;
8616 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8617 return NULL;
8618 if (setresgid(rgid, egid, sgid) < 0)
8619 return posix_error();
8620 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008621}
8622#endif
8623
8624#ifdef HAVE_GETRESUID
8625PyDoc_STRVAR(posix_getresuid__doc__,
8626"getresuid() -> (ruid, euid, suid)\n\n\
8627Get tuple of the current process's real, effective, and saved user ids.");
8628
8629static PyObject*
8630posix_getresuid (PyObject *self, PyObject *noargs)
8631{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008632 uid_t ruid, euid, suid;
8633 long l_ruid, l_euid, l_suid;
8634 if (getresuid(&ruid, &euid, &suid) < 0)
8635 return posix_error();
8636 /* Force the values into long's as we don't know the size of uid_t. */
8637 l_ruid = ruid;
8638 l_euid = euid;
8639 l_suid = suid;
8640 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008641}
8642#endif
8643
8644#ifdef HAVE_GETRESGID
8645PyDoc_STRVAR(posix_getresgid__doc__,
8646"getresgid() -> (rgid, egid, sgid)\n\n\
Georg Brandl21946af2010-10-06 09:28:45 +00008647Get tuple of the current process's real, effective, and saved group ids.");
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008648
8649static PyObject*
8650posix_getresgid (PyObject *self, PyObject *noargs)
8651{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008652 uid_t rgid, egid, sgid;
8653 long l_rgid, l_egid, l_sgid;
8654 if (getresgid(&rgid, &egid, &sgid) < 0)
8655 return posix_error();
8656 /* Force the values into long's as we don't know the size of uid_t. */
8657 l_rgid = rgid;
8658 l_egid = egid;
8659 l_sgid = sgid;
8660 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008661}
8662#endif
8663
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008664static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008665 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008666#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008667 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008668#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008669 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008670#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008671 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008672#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008673 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008674#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008675 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008676#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008677#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008678 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008679#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008680#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008681 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008682#endif /* HAVE_LCHMOD */
8683#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008684 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008685#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008686#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008687 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008688#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008689#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008690 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008691#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008692#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008693 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008694#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008695#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008696 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008697#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008698#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008699 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008700#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008701 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008702#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008703#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008704#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008705 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008706#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008707 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8708 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8709 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008710#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008711 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008712#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008713#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008714 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008715#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008716 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8717 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8718 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8719 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008720#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008721 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008722#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008723#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008724 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008725#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008726 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008727#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008728 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008729#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008730 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8731 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8732 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008733#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008734 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008735#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008736 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008737#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008738 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8739 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008740#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008741#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008742 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8743 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008744#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008745 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8746 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008747#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008748#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008749#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008750 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008751#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008752#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008753 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008754#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008755#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008756 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008757#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008758#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008759 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008760#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008761#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008762 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008763#endif /* HAVE_GETEGID */
8764#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008765 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008766#endif /* HAVE_GETEUID */
8767#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008768 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008769#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008770#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008771 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008772#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008773 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008774#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008775 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008776#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008777#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008778 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008779#endif /* HAVE_GETPPID */
8780#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008781 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008782#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008783#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008784 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008785#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008786#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008787 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008788#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008789#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008790 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008791#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008792#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008793 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008794#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008795#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008796 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008797#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008798 {"popen2", win32_popen2, METH_VARARGS},
8799 {"popen3", win32_popen3, METH_VARARGS},
8800 {"popen4", win32_popen4, METH_VARARGS},
8801 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8802 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008803#else
8804#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008805 {"popen2", os2emx_popen2, METH_VARARGS},
8806 {"popen3", os2emx_popen3, METH_VARARGS},
8807 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008808#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008809#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008810#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008811#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008812 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008813#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008814#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008815 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008816#endif /* HAVE_SETEUID */
8817#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008818 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008819#endif /* HAVE_SETEGID */
8820#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008821 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008822#endif /* HAVE_SETREUID */
8823#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008824 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008825#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008826#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008827 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008828#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008829#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008830 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008831#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008832#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008834#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008835#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008836 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008837#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008838#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008839 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008840#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008841#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008842 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008843#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008844#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008845 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008846#endif /* HAVE_WAIT3 */
8847#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008848 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008849#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008850#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008852#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008853#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008854 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008855#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008856#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008857 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008858#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008859#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008860 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008861#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008862#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008864#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008865#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008866 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008867#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008868 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8869 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8870 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8871 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8872 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8873 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8874 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8875 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8876 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8877 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8878 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008879#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008880 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008881#endif
8882#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008883 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008884#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008885#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008886 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008887#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008888#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008889 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8890 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8891 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008892#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008893#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008894 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008895#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008896#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008897 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008898#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008899#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008900 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008901#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008902 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008903#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008904 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008905#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008906#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008908#endif
8909#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008910 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008911#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008912#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008913#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008914 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008915#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008916#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008917 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008918#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008919#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008920 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008921#endif /* WIFSTOPPED */
8922#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008923 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008924#endif /* WIFSIGNALED */
8925#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008926 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008927#endif /* WIFEXITED */
8928#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008930#endif /* WEXITSTATUS */
8931#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008932 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008933#endif /* WTERMSIG */
8934#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008935 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008936#endif /* WSTOPSIG */
8937#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008938#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008939 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008940#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008941#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008942 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008943#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008944#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008945 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008946#endif
8947#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008948 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008949#endif
8950#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008951 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008952#endif
Fred Drakec9680921999-12-13 16:37:25 +00008953#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008954 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008955#endif
8956#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008957 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008958#endif
8959#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008960 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008961#endif
8962#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008963 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008964#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008965 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008966#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008967 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008968#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008969#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008970 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008971#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008972 #ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008973 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008974 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008975 #ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008976 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008977 #endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008978#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008979 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008980#endif
8981#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008982 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008983#endif
8984#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008985 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008986#endif
8987#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008988 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008989#endif
8990
Victor Stinnerd6f85422010-05-05 23:33:33 +00008991 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008992};
8993
8994
Barry Warsaw4a342091996-12-19 23:50:02 +00008995static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008996ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008997{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008998 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008999}
9000
Guido van Rossumd48f2521997-12-05 22:19:34 +00009001#if defined(PYOS_OS2)
9002/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009003static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009004{
9005 APIRET rc;
9006 ULONG values[QSV_MAX+1];
9007 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00009008 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00009009
9010 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00009011 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009012 Py_END_ALLOW_THREADS
9013
9014 if (rc != NO_ERROR) {
9015 os2_error(rc);
9016 return -1;
9017 }
9018
Fred Drake4d1e64b2002-04-15 19:40:07 +00009019 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
9020 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
9021 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
9022 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
9023 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
9024 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
9025 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009026
9027 switch (values[QSV_VERSION_MINOR]) {
9028 case 0: ver = "2.00"; break;
9029 case 10: ver = "2.10"; break;
9030 case 11: ver = "2.11"; break;
9031 case 30: ver = "3.00"; break;
9032 case 40: ver = "4.00"; break;
9033 case 50: ver = "5.00"; break;
9034 default:
Tim Peters885d4572001-11-28 20:27:42 +00009035 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00009036 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00009037 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009038 ver = &tmp[0];
9039 }
9040
9041 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00009042 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00009043 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009044
9045 /* Add Indicator of Which Drive was Used to Boot the System */
9046 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
9047 tmp[1] = ':';
9048 tmp[2] = '\0';
9049
Fred Drake4d1e64b2002-04-15 19:40:07 +00009050 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00009051}
9052#endif
9053
Barry Warsaw4a342091996-12-19 23:50:02 +00009054static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009055all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00009056{
Guido van Rossum94f6f721999-01-06 18:42:14 +00009057#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009059#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009060#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009061 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009062#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009063#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009064 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009065#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009066#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009067 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009068#endif
Fred Drakec9680921999-12-13 16:37:25 +00009069#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009070 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009071#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009072#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009073 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009074#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009075#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009076 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009077#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009078#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009079 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009080#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009081#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009082 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009083#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009084#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009085 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009086#endif
9087#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009088 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009089#endif
9090#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009091 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009092#endif
9093#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009094 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009095#endif
9096#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009097 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009098#endif
9099#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009101#endif
9102#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009103 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009104#endif
9105#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009106 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009107#endif
9108#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009109 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009110#endif
9111#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009112 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009113#endif
9114#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009115 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009116#endif
9117#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009119#endif
9120#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009122#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009123#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009124 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009125#endif
9126#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009127 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009128#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009129#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009131#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009132#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009133 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009134#endif
9135#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009136 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009137#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009138
Tim Peters5aa91602002-01-30 05:46:57 +00009139/* MS Windows */
9140#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009141 /* Don't inherit in child processes. */
9142 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009143#endif
9144#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009145 /* Optimize for short life (keep in memory). */
9146 /* MS forgot to define this one with a non-underscore form too. */
9147 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009148#endif
9149#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009150 /* Automatically delete when last handle is closed. */
9151 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009152#endif
9153#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009154 /* Optimize for random access. */
9155 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009156#endif
9157#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009158 /* Optimize for sequential access. */
9159 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009160#endif
9161
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009162/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009163#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009164 /* Send a SIGIO signal whenever input or output
9165 becomes available on file descriptor */
9166 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009167#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009168#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009169 /* Direct disk access. */
9170 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009171#endif
9172#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009173 /* Must be a directory. */
9174 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009175#endif
9176#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009177 /* Do not follow links. */
9178 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009179#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009180#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009181 /* Do not update the access time. */
9182 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009183#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009184
Victor Stinnerd6f85422010-05-05 23:33:33 +00009185 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009186#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009187 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009188#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009189#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009190 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009191#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009192#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009193 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009194#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009195#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009196 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009197#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009198#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009199 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009200#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009201#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009202 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009203#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009204#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009205 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009206#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009207#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009208 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009209#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009210#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009211 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009212#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009213#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009214 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009215#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009216#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009217 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009218#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009219#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009220 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009221#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009222#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009223 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009224#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009225#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009226 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009227#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009228#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009229 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009230#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009231#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009232 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009233#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009234#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009235 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009236#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009237
Guido van Rossum246bc171999-02-01 23:54:31 +00009238#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009239#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009240 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9241 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9242 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9243 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9244 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9245 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9246 if (ins(d, "P_PM", (long)P_PM)) return -1;
9247 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9248 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9249 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9250 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9251 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9252 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9253 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9254 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9255 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9256 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9257 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9258 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9259 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009260#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9262 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9263 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9264 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9265 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009266#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009267#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009268
Guido van Rossumd48f2521997-12-05 22:19:34 +00009269#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009270 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009271#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009272 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009273}
9274
9275
Tim Peters5aa91602002-01-30 05:46:57 +00009276#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009277#define INITFUNC initnt
9278#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009279
9280#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009281#define INITFUNC initos2
9282#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009283
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009284#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009285#define INITFUNC initposix
9286#define MODNAME "posix"
9287#endif
9288
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009289PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009290INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009291{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009292 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009293
Victor Stinnerd6f85422010-05-05 23:33:33 +00009294 m = Py_InitModule3(MODNAME,
9295 posix_methods,
9296 posix__doc__);
9297 if (m == NULL)
9298 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009299
Victor Stinnerd6f85422010-05-05 23:33:33 +00009300 /* Initialize environ dictionary */
9301 v = convertenviron();
9302 Py_XINCREF(v);
9303 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9304 return;
9305 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009306
Victor Stinnerd6f85422010-05-05 23:33:33 +00009307 if (all_ins(m))
9308 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009309
Victor Stinnerd6f85422010-05-05 23:33:33 +00009310 if (setup_confname_tables(m))
9311 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009312
Victor Stinnerd6f85422010-05-05 23:33:33 +00009313 Py_INCREF(PyExc_OSError);
9314 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009315
Guido van Rossumb3d39562000-01-31 18:41:26 +00009316#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009317 if (posix_putenv_garbage == NULL)
9318 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009319#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009320
Victor Stinnerd6f85422010-05-05 23:33:33 +00009321 if (!initialized) {
9322 stat_result_desc.name = MODNAME ".stat_result";
9323 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9324 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9325 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9326 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9327 structseq_new = StatResultType.tp_new;
9328 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009329
Victor Stinnerd6f85422010-05-05 23:33:33 +00009330 statvfs_result_desc.name = MODNAME ".statvfs_result";
9331 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009332#ifdef NEED_TICKS_PER_SECOND
9333# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009334 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009335# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009336 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009337# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009338 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009339# endif
9340#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009341 }
9342 Py_INCREF((PyObject*) &StatResultType);
9343 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9344 Py_INCREF((PyObject*) &StatVFSResultType);
9345 PyModule_AddObject(m, "statvfs_result",
9346 (PyObject*) &StatVFSResultType);
9347 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009348
9349#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009350 /*
9351 * Step 2 of weak-linking support on Mac OS X.
9352 *
9353 * The code below removes functions that are not available on the
9354 * currently active platform.
9355 *
9356 * This block allow one to use a python binary that was build on
9357 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9358 * OSX 10.4.
9359 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009360#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009361 if (fstatvfs == NULL) {
9362 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9363 return;
9364 }
9365 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009366#endif /* HAVE_FSTATVFS */
9367
9368#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009369 if (statvfs == NULL) {
9370 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9371 return;
9372 }
9373 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009374#endif /* HAVE_STATVFS */
9375
9376# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009377 if (lchown == NULL) {
9378 if (PyObject_DelAttrString(m, "lchown") == -1) {
9379 return;
9380 }
9381 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009382#endif /* HAVE_LCHOWN */
9383
9384
9385#endif /* __APPLE__ */
9386
Guido van Rossumb6775db1994-08-01 11:34:53 +00009387}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009388
9389#ifdef __cplusplus
9390}
9391#endif
9392
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009393