blob: 17af5086613d9c37e7641beb58adc666c3cf71ae [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;
861 int st_atime;
862 int st_atime_nsec;
863 int st_mtime;
864 int st_mtime_nsec;
865 int st_ctime;
866 int st_ctime_nsec;
867};
868
869static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
870
871static void
872FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
873{
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. */
880 /* XXX Win32 supports time stamps past 2038; we currently don't */
881 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
Martin v. Löwis14694662006-02-03 12:54:16 +0000882}
883
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000884static void
885time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
886{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000887 /* XXX endianness */
888 __int64 out;
889 out = time_in + secs_between_epochs;
890 out = out * 10000000 + nsec_in / 100;
891 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000892}
893
Martin v. Löwis14694662006-02-03 12:54:16 +0000894/* Below, we *know* that ugo+r is 0444 */
895#if _S_IREAD != 0400
896#error Unsupported C library
897#endif
898static int
899attributes_to_mode(DWORD attr)
900{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000901 int m = 0;
902 if (attr & FILE_ATTRIBUTE_DIRECTORY)
903 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
904 else
905 m |= _S_IFREG;
906 if (attr & FILE_ATTRIBUTE_READONLY)
907 m |= 0444;
908 else
909 m |= 0666;
910 return m;
Martin v. Löwis14694662006-02-03 12:54:16 +0000911}
912
913static int
914attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
915{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000916 memset(result, 0, sizeof(*result));
917 result->st_mode = attributes_to_mode(info->dwFileAttributes);
918 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
919 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
920 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
921 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
Martin v. Löwis14694662006-02-03 12:54:16 +0000922
Victor Stinnerd6f85422010-05-05 23:33:33 +0000923 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +0000924}
925
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000926static BOOL
927attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
928{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000929 HANDLE hFindFile;
930 WIN32_FIND_DATAA FileData;
931 hFindFile = FindFirstFileA(pszFile, &FileData);
932 if (hFindFile == INVALID_HANDLE_VALUE)
933 return FALSE;
934 FindClose(hFindFile);
935 pfad->dwFileAttributes = FileData.dwFileAttributes;
936 pfad->ftCreationTime = FileData.ftCreationTime;
937 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
938 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
939 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
940 pfad->nFileSizeLow = FileData.nFileSizeLow;
941 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000942}
943
944static BOOL
945attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
946{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000947 HANDLE hFindFile;
948 WIN32_FIND_DATAW FileData;
949 hFindFile = FindFirstFileW(pszFile, &FileData);
950 if (hFindFile == INVALID_HANDLE_VALUE)
951 return FALSE;
952 FindClose(hFindFile);
953 pfad->dwFileAttributes = FileData.dwFileAttributes;
954 pfad->ftCreationTime = FileData.ftCreationTime;
955 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
956 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
957 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
958 pfad->nFileSizeLow = FileData.nFileSizeLow;
959 return TRUE;
Martin v. Löwis3bf573f2007-04-04 18:30:36 +0000960}
961
Victor Stinnerd6f85422010-05-05 23:33:33 +0000962static int
Martin v. Löwis14694662006-02-03 12:54:16 +0000963win32_stat(const char* path, struct win32_stat *result)
964{
Victor Stinnerd6f85422010-05-05 23:33:33 +0000965 WIN32_FILE_ATTRIBUTE_DATA info;
966 int code;
967 char *dot;
968 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
969 if (GetLastError() != ERROR_SHARING_VIOLATION) {
970 /* Protocol violation: we explicitly clear errno, instead of
971 setting it to a POSIX error. Callers should use GetLastError. */
972 errno = 0;
973 return -1;
974 } else {
975 /* Could not get attributes on open file. Fall back to
976 reading the directory. */
977 if (!attributes_from_dir(path, &info)) {
978 /* Very strange. This should not fail now */
979 errno = 0;
980 return -1;
981 }
982 }
983 }
984 code = attribute_data_to_stat(&info, result);
985 if (code != 0)
986 return code;
987 /* Set S_IFEXEC if it is an .exe, .bat, ... */
988 dot = strrchr(path, '.');
989 if (dot) {
990 if (stricmp(dot, ".bat") == 0 ||
991 stricmp(dot, ".cmd") == 0 ||
992 stricmp(dot, ".exe") == 0 ||
993 stricmp(dot, ".com") == 0)
994 result->st_mode |= 0111;
995 }
996 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +0000997}
998
Victor Stinnerd6f85422010-05-05 23:33:33 +0000999static int
Martin v. Löwis14694662006-02-03 12:54:16 +00001000win32_wstat(const wchar_t* path, struct win32_stat *result)
1001{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001002 int code;
1003 const wchar_t *dot;
1004 WIN32_FILE_ATTRIBUTE_DATA info;
1005 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
1006 if (GetLastError() != ERROR_SHARING_VIOLATION) {
1007 /* Protocol violation: we explicitly clear errno, instead of
1008 setting it to a POSIX error. Callers should use GetLastError. */
1009 errno = 0;
1010 return -1;
1011 } else {
1012 /* Could not get attributes on open file. Fall back to
1013 reading the directory. */
1014 if (!attributes_from_dir_w(path, &info)) {
1015 /* Very strange. This should not fail now */
1016 errno = 0;
1017 return -1;
1018 }
1019 }
1020 }
1021 code = attribute_data_to_stat(&info, result);
1022 if (code < 0)
1023 return code;
1024 /* Set IFEXEC if it is an .exe, .bat, ... */
1025 dot = wcsrchr(path, '.');
1026 if (dot) {
1027 if (_wcsicmp(dot, L".bat") == 0 ||
1028 _wcsicmp(dot, L".cmd") == 0 ||
1029 _wcsicmp(dot, L".exe") == 0 ||
1030 _wcsicmp(dot, L".com") == 0)
1031 result->st_mode |= 0111;
1032 }
1033 return code;
Martin v. Löwis14694662006-02-03 12:54:16 +00001034}
1035
1036static int
1037win32_fstat(int file_number, struct win32_stat *result)
1038{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001039 BY_HANDLE_FILE_INFORMATION info;
1040 HANDLE h;
1041 int type;
Martin v. Löwis14694662006-02-03 12:54:16 +00001042
Victor Stinnerd6f85422010-05-05 23:33:33 +00001043 h = (HANDLE)_get_osfhandle(file_number);
Martin v. Löwis14694662006-02-03 12:54:16 +00001044
Victor Stinnerd6f85422010-05-05 23:33:33 +00001045 /* Protocol violation: we explicitly clear errno, instead of
1046 setting it to a POSIX error. Callers should use GetLastError. */
1047 errno = 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001048
Victor Stinnerd6f85422010-05-05 23:33:33 +00001049 if (h == INVALID_HANDLE_VALUE) {
1050 /* This is really a C library error (invalid file handle).
1051 We set the Win32 error to the closes one matching. */
1052 SetLastError(ERROR_INVALID_HANDLE);
1053 return -1;
1054 }
1055 memset(result, 0, sizeof(*result));
Martin v. Löwis14694662006-02-03 12:54:16 +00001056
Victor Stinnerd6f85422010-05-05 23:33:33 +00001057 type = GetFileType(h);
1058 if (type == FILE_TYPE_UNKNOWN) {
1059 DWORD error = GetLastError();
1060 if (error != 0) {
1061 return -1;
1062 }
1063 /* else: valid but unknown file */
1064 }
Martin v. Löwis14694662006-02-03 12:54:16 +00001065
Victor Stinnerd6f85422010-05-05 23:33:33 +00001066 if (type != FILE_TYPE_DISK) {
1067 if (type == FILE_TYPE_CHAR)
1068 result->st_mode = _S_IFCHR;
1069 else if (type == FILE_TYPE_PIPE)
1070 result->st_mode = _S_IFIFO;
1071 return 0;
1072 }
1073
1074 if (!GetFileInformationByHandle(h, &info)) {
1075 return -1;
1076 }
1077
1078 /* similar to stat() */
1079 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1080 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1081 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1082 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1083 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1084 /* specific to fstat() */
1085 result->st_nlink = info.nNumberOfLinks;
1086 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1087 return 0;
Martin v. Löwis14694662006-02-03 12:54:16 +00001088}
1089
1090#endif /* MS_WINDOWS */
1091
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001092PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001093"stat_result: Result from stat or lstat.\n\n\
1094This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001095 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001096or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1097\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001098Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1099or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001101See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102
1103static PyStructSequence_Field stat_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001104 {"st_mode", "protection bits"},
1105 {"st_ino", "inode"},
1106 {"st_dev", "device"},
1107 {"st_nlink", "number of hard links"},
1108 {"st_uid", "user ID of owner"},
1109 {"st_gid", "group ID of owner"},
1110 {"st_size", "total size, in bytes"},
1111 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1112 {NULL, "integer time of last access"},
1113 {NULL, "integer time of last modification"},
1114 {NULL, "integer time of last change"},
1115 {"st_atime", "time of last access"},
1116 {"st_mtime", "time of last modification"},
1117 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001118#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001119 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001120#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001121#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001122 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001123#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001124#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001125 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001126#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001127#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001128 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001129#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001130#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001131 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001132#endif
1133#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001134 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001135#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001136 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001137};
1138
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001139#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001140#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001141#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001142#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001143#endif
1144
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001145#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001146#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1147#else
1148#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1149#endif
1150
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001151#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001152#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1153#else
1154#define ST_RDEV_IDX ST_BLOCKS_IDX
1155#endif
1156
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001157#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1158#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1159#else
1160#define ST_FLAGS_IDX ST_RDEV_IDX
1161#endif
1162
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001163#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001164#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001165#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001166#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001167#endif
1168
1169#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1170#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1171#else
1172#define ST_BIRTHTIME_IDX ST_GEN_IDX
1173#endif
1174
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001175static PyStructSequence_Desc stat_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001176 "stat_result", /* name */
1177 stat_result__doc__, /* doc */
1178 stat_result_fields,
1179 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001180};
1181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001182PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001183"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1184This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001185 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001186or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001188See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001189
1190static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001191 {"f_bsize", },
1192 {"f_frsize", },
1193 {"f_blocks", },
1194 {"f_bfree", },
1195 {"f_bavail", },
1196 {"f_files", },
1197 {"f_ffree", },
1198 {"f_favail", },
1199 {"f_flag", },
1200 {"f_namemax",},
1201 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001202};
1203
1204static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00001205 "statvfs_result", /* name */
1206 statvfs_result__doc__, /* doc */
1207 statvfs_result_fields,
1208 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001209};
1210
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001211static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001212static PyTypeObject StatResultType;
1213static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001214static newfunc structseq_new;
1215
1216static PyObject *
1217statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1218{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001219 PyStructSequence *result;
1220 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001221
Victor Stinnerd6f85422010-05-05 23:33:33 +00001222 result = (PyStructSequence*)structseq_new(type, args, kwds);
1223 if (!result)
1224 return NULL;
1225 /* If we have been initialized from a tuple,
1226 st_?time might be set to None. Initialize it
1227 from the int slots. */
1228 for (i = 7; i <= 9; i++) {
1229 if (result->ob_item[i+3] == Py_None) {
1230 Py_DECREF(Py_None);
1231 Py_INCREF(result->ob_item[i]);
1232 result->ob_item[i+3] = result->ob_item[i];
1233 }
1234 }
1235 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001236}
1237
1238
1239
1240/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001241static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001242
1243PyDoc_STRVAR(stat_float_times__doc__,
1244"stat_float_times([newval]) -> oldval\n\n\
1245Determine whether os.[lf]stat represents time stamps as float objects.\n\
1246If newval is True, future calls to stat() return floats, if it is False,\n\
1247future calls return ints. \n\
1248If newval is omitted, return the current setting.\n");
1249
1250static PyObject*
1251stat_float_times(PyObject* self, PyObject *args)
1252{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001253 int newval = -1;
1254 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1255 return NULL;
1256 if (newval == -1)
1257 /* Return old value */
1258 return PyBool_FromLong(_stat_float_times);
1259 _stat_float_times = newval;
1260 Py_INCREF(Py_None);
1261 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001262}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001263
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001264static void
1265fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1266{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001267 PyObject *fval,*ival;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001268#if SIZEOF_TIME_T > SIZEOF_LONG
Victor Stinnerd6f85422010-05-05 23:33:33 +00001269 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001270#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001271 ival = PyInt_FromLong((long)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001272#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001273 if (!ival)
1274 return;
1275 if (_stat_float_times) {
1276 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1277 } else {
1278 fval = ival;
1279 Py_INCREF(fval);
1280 }
1281 PyStructSequence_SET_ITEM(v, index, ival);
1282 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001283}
1284
Tim Peters5aa91602002-01-30 05:46:57 +00001285/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001286 (used by posix_stat() and posix_fstat()) */
1287static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001288_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001289{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001290 unsigned long ansec, mnsec, cnsec;
1291 PyObject *v = PyStructSequence_New(&StatResultType);
1292 if (v == NULL)
1293 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001294
Victor Stinnerd6f85422010-05-05 23:33:33 +00001295 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001296#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001297 PyStructSequence_SET_ITEM(v, 1,
1298 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001299#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001300 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001301#endif
1302#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001303 PyStructSequence_SET_ITEM(v, 2,
1304 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001305#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001306 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001307#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001308 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1309 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1310 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001311#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinnerd6f85422010-05-05 23:33:33 +00001312 PyStructSequence_SET_ITEM(v, 6,
1313 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001314#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001315 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001316#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001317
Martin v. Löwis14694662006-02-03 12:54:16 +00001318#if defined(HAVE_STAT_TV_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001319 ansec = st->st_atim.tv_nsec;
1320 mnsec = st->st_mtim.tv_nsec;
1321 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001322#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001323 ansec = st->st_atimespec.tv_nsec;
1324 mnsec = st->st_mtimespec.tv_nsec;
1325 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001326#elif defined(HAVE_STAT_NSEC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001327 ansec = st->st_atime_nsec;
1328 mnsec = st->st_mtime_nsec;
1329 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001330#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001331 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001332#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001333 fill_time(v, 7, st->st_atime, ansec);
1334 fill_time(v, 8, st->st_mtime, mnsec);
1335 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001336
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001337#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00001338 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1339 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001340#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001341#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001342 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1343 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001344#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001345#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00001346 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1347 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001348#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001349#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00001350 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1351 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001352#endif
1353#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00001354 {
1355 PyObject *val;
1356 unsigned long bsec,bnsec;
1357 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001358#ifdef HAVE_STAT_TV_NSEC2
Victor Stinnerd6f85422010-05-05 23:33:33 +00001359 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001360#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001361 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001362#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001363 if (_stat_float_times) {
1364 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1365 } else {
1366 val = PyInt_FromLong((long)bsec);
1367 }
1368 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1369 val);
1370 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001371#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001372#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001373 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1374 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001375#endif
Fred Drake699f3522000-06-29 21:12:41 +00001376
Victor Stinnerd6f85422010-05-05 23:33:33 +00001377 if (PyErr_Occurred()) {
1378 Py_DECREF(v);
1379 return NULL;
1380 }
Fred Drake699f3522000-06-29 21:12:41 +00001381
Victor Stinnerd6f85422010-05-05 23:33:33 +00001382 return v;
Fred Drake699f3522000-06-29 21:12:41 +00001383}
1384
Martin v. Löwisd8948722004-06-02 09:57:56 +00001385#ifdef MS_WINDOWS
1386
1387/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1388 where / can be used in place of \ and the trailing slash is optional.
1389 Both SERVER and SHARE must have at least one character.
1390*/
1391
1392#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1393#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001394#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001395#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001396#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001397
Tim Peters4ad82172004-08-30 17:02:04 +00001398static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001399IsUNCRootA(char *path, int pathlen)
1400{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001401 #define ISSLASH ISSLASHA
Martin v. Löwisd8948722004-06-02 09:57:56 +00001402
Victor Stinnerd6f85422010-05-05 23:33:33 +00001403 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001404
Victor Stinnerd6f85422010-05-05 23:33:33 +00001405 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1406 /* minimum UNCRoot is \\x\y */
1407 return FALSE;
1408 for (i = 2; i < pathlen ; i++)
1409 if (ISSLASH(path[i])) break;
1410 if (i == 2 || i == pathlen)
1411 /* do not allow \\\SHARE or \\SERVER */
1412 return FALSE;
1413 share = i+1;
1414 for (i = share; i < pathlen; i++)
1415 if (ISSLASH(path[i])) break;
1416 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001417
Victor Stinnerd6f85422010-05-05 23:33:33 +00001418 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001419}
1420
Tim Peters4ad82172004-08-30 17:02:04 +00001421static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001422IsUNCRootW(Py_UNICODE *path, int pathlen)
1423{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001424 #define ISSLASH ISSLASHW
Martin v. Löwisd8948722004-06-02 09:57:56 +00001425
Victor Stinnerd6f85422010-05-05 23:33:33 +00001426 int i, share;
Martin v. Löwisd8948722004-06-02 09:57:56 +00001427
Victor Stinnerd6f85422010-05-05 23:33:33 +00001428 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1429 /* minimum UNCRoot is \\x\y */
1430 return FALSE;
1431 for (i = 2; i < pathlen ; i++)
1432 if (ISSLASH(path[i])) break;
1433 if (i == 2 || i == pathlen)
1434 /* do not allow \\\SHARE or \\SERVER */
1435 return FALSE;
1436 share = i+1;
1437 for (i = share; i < pathlen; i++)
1438 if (ISSLASH(path[i])) break;
1439 return (i != share && (i == pathlen || i == pathlen-1));
Martin v. Löwisd8948722004-06-02 09:57:56 +00001440
Victor Stinnerd6f85422010-05-05 23:33:33 +00001441 #undef ISSLASH
Martin v. Löwisd8948722004-06-02 09:57:56 +00001442}
Martin v. Löwisd8948722004-06-02 09:57:56 +00001443#endif /* MS_WINDOWS */
1444
Barry Warsaw53699e91996-12-10 23:23:01 +00001445static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001446posix_do_stat(PyObject *self, PyObject *args,
Victor Stinnerd6f85422010-05-05 23:33:33 +00001447 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001449 int (*statfunc)(const char *, STRUCT_STAT *, ...),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001450#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001451 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001452#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001453 char *wformat,
1454 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001455{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001456 STRUCT_STAT st;
1457 char *path = NULL; /* pass this to stat; do not free() it */
1458 char *pathfree = NULL; /* this memory must be free'd */
1459 int res;
1460 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001462#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001463 PyUnicodeObject *po;
1464 if (PyArg_ParseTuple(args, wformat, &po)) {
1465 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
Martin v. Löwis14694662006-02-03 12:54:16 +00001466
Victor Stinnerd6f85422010-05-05 23:33:33 +00001467 Py_BEGIN_ALLOW_THREADS
1468 /* PyUnicode_AS_UNICODE result OK without
1469 thread lock as it is a simple dereference. */
1470 res = wstatfunc(wpath, &st);
1471 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001472
Victor Stinnerd6f85422010-05-05 23:33:33 +00001473 if (res != 0)
1474 return win32_error_unicode("stat", wpath);
1475 return _pystat_fromstructstat(&st);
1476 }
1477 /* Drop the argument parsing error as narrow strings
1478 are also valid. */
1479 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001480#endif
1481
Victor Stinnerd6f85422010-05-05 23:33:33 +00001482 if (!PyArg_ParseTuple(args, format,
1483 Py_FileSystemDefaultEncoding, &path))
1484 return NULL;
1485 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001486
Victor Stinnerd6f85422010-05-05 23:33:33 +00001487 Py_BEGIN_ALLOW_THREADS
1488 res = (*statfunc)(path, &st);
1489 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001490
Victor Stinnerd6f85422010-05-05 23:33:33 +00001491 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001492#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001493 result = win32_error("stat", pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001494#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001495 result = posix_error_with_filename(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001496#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001497 }
1498 else
1499 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001500
Victor Stinnerd6f85422010-05-05 23:33:33 +00001501 PyMem_Free(pathfree);
1502 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503}
1504
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001505/* POSIX methods */
1506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507PyDoc_STRVAR(posix_access__doc__,
Georg Brandl7a284472007-01-27 19:38:50 +00001508"access(path, mode) -> True if granted, False otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001509Use the real uid/gid to test for access to a path. Note that most\n\
1510operations will use the effective uid/gid, therefore this routine can\n\
1511be used in a suid/sgid environment to test if the invoking user has the\n\
1512specified access to the path. The mode argument can be F_OK to test\n\
1513existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001514
1515static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001516posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001517{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001518 char *path;
1519 int mode;
1520
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001521#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001522 DWORD attr;
1523 PyUnicodeObject *po;
1524 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1525 Py_BEGIN_ALLOW_THREADS
1526 /* PyUnicode_AS_UNICODE OK without thread lock as
1527 it is a simple dereference. */
1528 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1529 Py_END_ALLOW_THREADS
1530 goto finish;
1531 }
1532 /* Drop the argument parsing error as narrow strings
1533 are also valid. */
1534 PyErr_Clear();
1535 if (!PyArg_ParseTuple(args, "eti:access",
1536 Py_FileSystemDefaultEncoding, &path, &mode))
1537 return NULL;
1538 Py_BEGIN_ALLOW_THREADS
1539 attr = GetFileAttributesA(path);
1540 Py_END_ALLOW_THREADS
1541 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001542finish:
Victor Stinnerd6f85422010-05-05 23:33:33 +00001543 if (attr == 0xFFFFFFFF)
1544 /* File does not exist, or cannot read attributes */
1545 return PyBool_FromLong(0);
1546 /* Access is possible if either write access wasn't requested, or
1547 the file isn't read-only, or if it's a directory, as there are
1548 no read-only directories on Windows. */
1549 return PyBool_FromLong(!(mode & 2)
1550 || !(attr & FILE_ATTRIBUTE_READONLY)
1551 || (attr & FILE_ATTRIBUTE_DIRECTORY));
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001552#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001553 int res;
1554 if (!PyArg_ParseTuple(args, "eti:access",
1555 Py_FileSystemDefaultEncoding, &path, &mode))
1556 return NULL;
1557 Py_BEGIN_ALLOW_THREADS
1558 res = access(path, mode);
1559 Py_END_ALLOW_THREADS
1560 PyMem_Free(path);
1561 return PyBool_FromLong(res == 0);
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001562#endif /* MS_WINDOWS */
Guido van Rossum94f6f721999-01-06 18:42:14 +00001563}
1564
Guido van Rossumd371ff11999-01-25 16:12:23 +00001565#ifndef F_OK
1566#define F_OK 0
1567#endif
1568#ifndef R_OK
1569#define R_OK 4
1570#endif
1571#ifndef W_OK
1572#define W_OK 2
1573#endif
1574#ifndef X_OK
1575#define X_OK 1
1576#endif
1577
1578#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001579PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001580"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001581Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001582
1583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001584posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001585{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001586 int id;
1587 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001588
Victor Stinnerd6f85422010-05-05 23:33:33 +00001589 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1590 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00001591
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001592#if defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001593 /* file descriptor 0 only, the default input device (stdin) */
1594 if (id == 0) {
1595 ret = ttyname();
1596 }
1597 else {
1598 ret = NULL;
1599 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001600#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001601 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001602#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001603 if (ret == NULL)
1604 return posix_error();
1605 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001606}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001607#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001611"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001612Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001613
1614static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001615posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001616{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001617 char *ret;
1618 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001619
Greg Wardb48bc172000-03-01 21:51:56 +00001620#ifdef USE_CTERMID_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00001621 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001622#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001623 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001624#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00001625 if (ret == NULL)
1626 return posix_error();
1627 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001628}
1629#endif
1630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001631PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001632"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001633Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001634
Barry Warsaw53699e91996-12-10 23:23:01 +00001635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001636posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001637{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001638#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001639 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001640#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001641 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001642#elif defined(__VMS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001643 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001644#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00001645 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001646#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001647}
1648
Fred Drake4d1e64b2002-04-15 19:40:07 +00001649#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001650PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001651"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001652Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001653opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001654
1655static PyObject *
1656posix_fchdir(PyObject *self, PyObject *fdobj)
1657{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001658 return posix_fildes(fdobj, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00001659}
1660#endif /* HAVE_FCHDIR */
1661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001663PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001664"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001665Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001666
Barry Warsaw53699e91996-12-10 23:23:01 +00001667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001668posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001670 char *path = NULL;
1671 int i;
1672 int res;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001673#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00001674 DWORD attr;
1675 PyUnicodeObject *po;
1676 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1677 Py_BEGIN_ALLOW_THREADS
1678 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1679 if (attr != 0xFFFFFFFF) {
1680 if (i & _S_IWRITE)
1681 attr &= ~FILE_ATTRIBUTE_READONLY;
1682 else
1683 attr |= FILE_ATTRIBUTE_READONLY;
1684 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1685 }
1686 else
1687 res = 0;
1688 Py_END_ALLOW_THREADS
1689 if (!res)
1690 return win32_error_unicode("chmod",
1691 PyUnicode_AS_UNICODE(po));
1692 Py_INCREF(Py_None);
1693 return Py_None;
1694 }
1695 /* Drop the argument parsing error as narrow strings
1696 are also valid. */
1697 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00001698
Victor Stinnerd6f85422010-05-05 23:33:33 +00001699 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1700 &path, &i))
1701 return NULL;
1702 Py_BEGIN_ALLOW_THREADS
1703 attr = GetFileAttributesA(path);
1704 if (attr != 0xFFFFFFFF) {
1705 if (i & _S_IWRITE)
1706 attr &= ~FILE_ATTRIBUTE_READONLY;
1707 else
1708 attr |= FILE_ATTRIBUTE_READONLY;
1709 res = SetFileAttributesA(path, attr);
1710 }
1711 else
1712 res = 0;
1713 Py_END_ALLOW_THREADS
1714 if (!res) {
1715 win32_error("chmod", path);
1716 PyMem_Free(path);
1717 return NULL;
1718 }
1719 PyMem_Free(path);
1720 Py_INCREF(Py_None);
1721 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00001722#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00001723 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1724 &path, &i))
1725 return NULL;
1726 Py_BEGIN_ALLOW_THREADS
1727 res = chmod(path, i);
1728 Py_END_ALLOW_THREADS
1729 if (res < 0)
1730 return posix_error_with_allocated_filename(path);
1731 PyMem_Free(path);
1732 Py_INCREF(Py_None);
1733 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001734#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001735}
1736
Christian Heimes36281872007-11-30 21:11:28 +00001737#ifdef HAVE_FCHMOD
1738PyDoc_STRVAR(posix_fchmod__doc__,
1739"fchmod(fd, mode)\n\n\
1740Change the access permissions of the file given by file\n\
1741descriptor fd.");
1742
1743static PyObject *
1744posix_fchmod(PyObject *self, PyObject *args)
1745{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001746 int fd, mode, res;
1747 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1748 return NULL;
1749 Py_BEGIN_ALLOW_THREADS
1750 res = fchmod(fd, mode);
1751 Py_END_ALLOW_THREADS
1752 if (res < 0)
1753 return posix_error();
1754 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001755}
1756#endif /* HAVE_FCHMOD */
1757
1758#ifdef HAVE_LCHMOD
1759PyDoc_STRVAR(posix_lchmod__doc__,
1760"lchmod(path, mode)\n\n\
1761Change the access permissions of a file. If path is a symlink, this\n\
1762affects the link itself rather than the target.");
1763
1764static PyObject *
1765posix_lchmod(PyObject *self, PyObject *args)
1766{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001767 char *path = NULL;
1768 int i;
1769 int res;
1770 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1771 &path, &i))
1772 return NULL;
1773 Py_BEGIN_ALLOW_THREADS
1774 res = lchmod(path, i);
1775 Py_END_ALLOW_THREADS
1776 if (res < 0)
1777 return posix_error_with_allocated_filename(path);
1778 PyMem_Free(path);
1779 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001780}
1781#endif /* HAVE_LCHMOD */
1782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783
Martin v. Löwis382abef2007-02-19 10:55:19 +00001784#ifdef HAVE_CHFLAGS
1785PyDoc_STRVAR(posix_chflags__doc__,
1786"chflags(path, flags)\n\n\
1787Set file flags.");
1788
1789static PyObject *
1790posix_chflags(PyObject *self, PyObject *args)
1791{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001792 char *path;
1793 unsigned long flags;
1794 int res;
1795 if (!PyArg_ParseTuple(args, "etk:chflags",
1796 Py_FileSystemDefaultEncoding, &path, &flags))
1797 return NULL;
1798 Py_BEGIN_ALLOW_THREADS
1799 res = chflags(path, flags);
1800 Py_END_ALLOW_THREADS
1801 if (res < 0)
1802 return posix_error_with_allocated_filename(path);
1803 PyMem_Free(path);
1804 Py_INCREF(Py_None);
1805 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001806}
1807#endif /* HAVE_CHFLAGS */
1808
1809#ifdef HAVE_LCHFLAGS
1810PyDoc_STRVAR(posix_lchflags__doc__,
1811"lchflags(path, flags)\n\n\
1812Set file flags.\n\
1813This function will not follow symbolic links.");
1814
1815static PyObject *
1816posix_lchflags(PyObject *self, PyObject *args)
1817{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001818 char *path;
1819 unsigned long flags;
1820 int res;
1821 if (!PyArg_ParseTuple(args, "etk:lchflags",
1822 Py_FileSystemDefaultEncoding, &path, &flags))
1823 return NULL;
1824 Py_BEGIN_ALLOW_THREADS
1825 res = lchflags(path, flags);
1826 Py_END_ALLOW_THREADS
1827 if (res < 0)
1828 return posix_error_with_allocated_filename(path);
1829 PyMem_Free(path);
1830 Py_INCREF(Py_None);
1831 return Py_None;
Martin v. Löwis382abef2007-02-19 10:55:19 +00001832}
1833#endif /* HAVE_LCHFLAGS */
1834
Martin v. Löwis244edc82001-10-04 22:44:26 +00001835#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001838Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001839
1840static PyObject *
1841posix_chroot(PyObject *self, PyObject *args)
1842{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001843 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001844}
1845#endif
1846
Guido van Rossum21142a01999-01-08 21:05:37 +00001847#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001848PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001849"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001851
1852static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001853posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001854{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001855 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001856}
1857#endif /* HAVE_FSYNC */
1858
1859#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001860
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001861#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001862extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1863#endif
1864
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001867force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001868 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001869
1870static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001871posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001872{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001873 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001874}
1875#endif /* HAVE_FDATASYNC */
1876
1877
Fredrik Lundh10723342000-07-10 16:38:09 +00001878#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001879PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001880"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001882
Barry Warsaw53699e91996-12-10 23:23:01 +00001883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001884posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001885{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001886 char *path = NULL;
1887 long uid, gid;
1888 int res;
1889 if (!PyArg_ParseTuple(args, "etll:chown",
1890 Py_FileSystemDefaultEncoding, &path,
1891 &uid, &gid))
1892 return NULL;
1893 Py_BEGIN_ALLOW_THREADS
1894 res = chown(path, (uid_t) uid, (gid_t) gid);
1895 Py_END_ALLOW_THREADS
1896 if (res < 0)
1897 return posix_error_with_allocated_filename(path);
1898 PyMem_Free(path);
1899 Py_INCREF(Py_None);
1900 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001902#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001903
Christian Heimes36281872007-11-30 21:11:28 +00001904#ifdef HAVE_FCHOWN
1905PyDoc_STRVAR(posix_fchown__doc__,
1906"fchown(fd, uid, gid)\n\n\
1907Change the owner and group id of the file given by file descriptor\n\
1908fd to the numeric uid and gid.");
1909
1910static PyObject *
1911posix_fchown(PyObject *self, PyObject *args)
1912{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001913 int fd;
1914 long uid, gid;
1915 int res;
1916 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
1917 return NULL;
1918 Py_BEGIN_ALLOW_THREADS
1919 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1920 Py_END_ALLOW_THREADS
1921 if (res < 0)
1922 return posix_error();
1923 Py_RETURN_NONE;
Christian Heimes36281872007-11-30 21:11:28 +00001924}
1925#endif /* HAVE_FCHOWN */
1926
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001927#ifdef HAVE_LCHOWN
1928PyDoc_STRVAR(posix_lchown__doc__,
1929"lchown(path, uid, gid)\n\n\
1930Change the owner and group id of path to the numeric uid and gid.\n\
1931This function will not follow symbolic links.");
1932
1933static PyObject *
1934posix_lchown(PyObject *self, PyObject *args)
1935{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001936 char *path = NULL;
1937 long uid, gid;
1938 int res;
1939 if (!PyArg_ParseTuple(args, "etll:lchown",
1940 Py_FileSystemDefaultEncoding, &path,
1941 &uid, &gid))
1942 return NULL;
1943 Py_BEGIN_ALLOW_THREADS
1944 res = lchown(path, (uid_t) uid, (gid_t) gid);
1945 Py_END_ALLOW_THREADS
1946 if (res < 0)
1947 return posix_error_with_allocated_filename(path);
1948 PyMem_Free(path);
1949 Py_INCREF(Py_None);
1950 return Py_None;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001951}
1952#endif /* HAVE_LCHOWN */
1953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Guido van Rossum36bc6801995-06-14 22:54:23 +00001955#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001956PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001957"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001958Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001959
Stefan Krah182ae642010-07-13 19:17:08 +00001960#if (defined(__sun) && defined(__SVR4)) || defined(__OpenBSD__)
1961/* Issue 9185: getcwd() returns NULL/ERANGE indefinitely. */
1962static PyObject *
1963posix_getcwd(PyObject *self, PyObject *noargs)
1964{
1965 char buf[PATH_MAX+2];
1966 char *res;
1967
1968 Py_BEGIN_ALLOW_THREADS
1969#if defined(PYOS_OS2) && defined(PYCC_GCC)
1970 res = _getcwd2(buf, sizeof buf);
1971#else
1972 res = getcwd(buf, sizeof buf);
1973#endif
1974 Py_END_ALLOW_THREADS
1975
1976 if (res == NULL)
1977 return posix_error();
1978
1979 return PyString_FromString(buf);
1980}
1981#else
Barry Warsaw53699e91996-12-10 23:23:01 +00001982static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001983posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984{
Victor Stinnerd6f85422010-05-05 23:33:33 +00001985 int bufsize_incr = 1024;
1986 int bufsize = 0;
1987 char *tmpbuf = NULL;
1988 char *res = NULL;
1989 PyObject *dynamic_return;
Neal Norwitze241ce82003-02-17 18:17:05 +00001990
Victor Stinnerd6f85422010-05-05 23:33:33 +00001991 Py_BEGIN_ALLOW_THREADS
1992 do {
1993 bufsize = bufsize + bufsize_incr;
1994 tmpbuf = malloc(bufsize);
1995 if (tmpbuf == NULL) {
1996 break;
1997 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001998#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00001999 res = _getcwd2(tmpbuf, bufsize);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00002000#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002001 res = getcwd(tmpbuf, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002002#endif
Facundo Batista5596b0c2008-06-22 13:36:20 +00002003
Victor Stinnerd6f85422010-05-05 23:33:33 +00002004 if (res == NULL) {
2005 free(tmpbuf);
2006 }
2007 } while ((res == NULL) && (errno == ERANGE));
2008 Py_END_ALLOW_THREADS
Facundo Batista5596b0c2008-06-22 13:36:20 +00002009
Victor Stinnerd6f85422010-05-05 23:33:33 +00002010 if (res == NULL)
2011 return posix_error();
Facundo Batista5596b0c2008-06-22 13:36:20 +00002012
Victor Stinnerd6f85422010-05-05 23:33:33 +00002013 dynamic_return = PyString_FromString(tmpbuf);
2014 free(tmpbuf);
Facundo Batista5596b0c2008-06-22 13:36:20 +00002015
Victor Stinnerd6f85422010-05-05 23:33:33 +00002016 return dynamic_return;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017}
Stefan Krah182ae642010-07-13 19:17:08 +00002018#endif /* getcwd() NULL/ERANGE workaround. */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002019
Walter Dörwald3b918c32002-11-21 20:18:46 +00002020#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002021PyDoc_STRVAR(posix_getcwdu__doc__,
2022"getcwdu() -> path\n\n\
2023Return a unicode string representing the current working directory.");
2024
2025static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002026posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002027{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002028 char buf[1026];
2029 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002030
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002031#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002032 DWORD len;
2033 wchar_t wbuf[1026];
2034 wchar_t *wbuf2 = wbuf;
2035 PyObject *resobj;
2036 Py_BEGIN_ALLOW_THREADS
2037 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2038 /* If the buffer is large enough, len does not include the
2039 terminating \0. If the buffer is too small, len includes
2040 the space needed for the terminator. */
2041 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2042 wbuf2 = malloc(len * sizeof(wchar_t));
2043 if (wbuf2)
2044 len = GetCurrentDirectoryW(len, wbuf2);
2045 }
2046 Py_END_ALLOW_THREADS
2047 if (!wbuf2) {
2048 PyErr_NoMemory();
2049 return NULL;
2050 }
2051 if (!len) {
2052 if (wbuf2 != wbuf) free(wbuf2);
2053 return win32_error("getcwdu", NULL);
2054 }
2055 resobj = PyUnicode_FromWideChar(wbuf2, len);
2056 if (wbuf2 != wbuf) free(wbuf2);
2057 return resobj;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002058#endif /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002059
Victor Stinnerd6f85422010-05-05 23:33:33 +00002060 Py_BEGIN_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002061#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002062 res = _getcwd2(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002063#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002064 res = getcwd(buf, sizeof buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002065#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002066 Py_END_ALLOW_THREADS
2067 if (res == NULL)
2068 return posix_error();
2069 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002070}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002071#endif /* Py_USING_UNICODE */
2072#endif /* HAVE_GETCWD */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Guido van Rossumb6775db1994-08-01 11:34:53 +00002075#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002076PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002077"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002079
Barry Warsaw53699e91996-12-10 23:23:01 +00002080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002081posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002082{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002083 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002084}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002085#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002088PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002089"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090Return a list containing the names of the entries in the directory.\n\
2091\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002092 path: path of directory to list\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093\n\
2094The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Barry Warsaw53699e91996-12-10 23:23:01 +00002097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002098posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00002099{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002100 /* XXX Should redo this putting the (now four) versions of opendir
2101 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002102#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002103
Victor Stinnerd6f85422010-05-05 23:33:33 +00002104 PyObject *d, *v;
2105 HANDLE hFindFile;
2106 BOOL result;
2107 WIN32_FIND_DATA FileData;
2108 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2109 char *bufptr = namebuf;
2110 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002111
Victor Stinnerd6f85422010-05-05 23:33:33 +00002112 PyObject *po;
2113 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2114 WIN32_FIND_DATAW wFileData;
2115 Py_UNICODE *wnamebuf;
2116 /* Overallocate for \\*.*\0 */
2117 len = PyUnicode_GET_SIZE(po);
2118 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2119 if (!wnamebuf) {
2120 PyErr_NoMemory();
2121 return NULL;
2122 }
2123 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2124 if (len > 0) {
2125 Py_UNICODE wch = wnamebuf[len-1];
2126 if (wch != L'/' && wch != L'\\' && wch != L':')
2127 wnamebuf[len++] = L'\\';
2128 wcscpy(wnamebuf + len, L"*.*");
2129 }
2130 if ((d = PyList_New(0)) == NULL) {
2131 free(wnamebuf);
2132 return NULL;
2133 }
2134 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2135 if (hFindFile == INVALID_HANDLE_VALUE) {
2136 int error = GetLastError();
2137 if (error == ERROR_FILE_NOT_FOUND) {
2138 free(wnamebuf);
2139 return d;
2140 }
2141 Py_DECREF(d);
2142 win32_error_unicode("FindFirstFileW", wnamebuf);
2143 free(wnamebuf);
2144 return NULL;
2145 }
2146 do {
2147 /* Skip over . and .. */
2148 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2149 wcscmp(wFileData.cFileName, L"..") != 0) {
2150 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2151 if (v == NULL) {
2152 Py_DECREF(d);
2153 d = NULL;
2154 break;
2155 }
2156 if (PyList_Append(d, v) != 0) {
2157 Py_DECREF(v);
2158 Py_DECREF(d);
2159 d = NULL;
2160 break;
2161 }
2162 Py_DECREF(v);
2163 }
2164 Py_BEGIN_ALLOW_THREADS
2165 result = FindNextFileW(hFindFile, &wFileData);
2166 Py_END_ALLOW_THREADS
2167 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2168 it got to the end of the directory. */
2169 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2170 Py_DECREF(d);
2171 win32_error_unicode("FindNextFileW", wnamebuf);
2172 FindClose(hFindFile);
2173 free(wnamebuf);
2174 return NULL;
2175 }
2176 } while (result == TRUE);
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002177
Victor Stinnerd6f85422010-05-05 23:33:33 +00002178 if (FindClose(hFindFile) == FALSE) {
2179 Py_DECREF(d);
2180 win32_error_unicode("FindClose", wnamebuf);
2181 free(wnamebuf);
2182 return NULL;
2183 }
2184 free(wnamebuf);
2185 return d;
2186 }
2187 /* Drop the argument parsing error as narrow strings
2188 are also valid. */
2189 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002190
Victor Stinnerd6f85422010-05-05 23:33:33 +00002191 if (!PyArg_ParseTuple(args, "et#:listdir",
2192 Py_FileSystemDefaultEncoding, &bufptr, &len))
2193 return NULL;
2194 if (len > 0) {
2195 char ch = namebuf[len-1];
2196 if (ch != SEP && ch != ALTSEP && ch != ':')
2197 namebuf[len++] = '/';
2198 strcpy(namebuf + len, "*.*");
2199 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002200
Victor Stinnerd6f85422010-05-05 23:33:33 +00002201 if ((d = PyList_New(0)) == NULL)
2202 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002203
Victor Stinnerd6f85422010-05-05 23:33:33 +00002204 hFindFile = FindFirstFile(namebuf, &FileData);
2205 if (hFindFile == INVALID_HANDLE_VALUE) {
2206 int error = GetLastError();
2207 if (error == ERROR_FILE_NOT_FOUND)
2208 return d;
2209 Py_DECREF(d);
2210 return win32_error("FindFirstFile", namebuf);
2211 }
2212 do {
2213 /* Skip over . and .. */
2214 if (strcmp(FileData.cFileName, ".") != 0 &&
2215 strcmp(FileData.cFileName, "..") != 0) {
2216 v = PyString_FromString(FileData.cFileName);
2217 if (v == NULL) {
2218 Py_DECREF(d);
2219 d = NULL;
2220 break;
2221 }
2222 if (PyList_Append(d, v) != 0) {
2223 Py_DECREF(v);
2224 Py_DECREF(d);
2225 d = NULL;
2226 break;
2227 }
2228 Py_DECREF(v);
2229 }
2230 Py_BEGIN_ALLOW_THREADS
2231 result = FindNextFile(hFindFile, &FileData);
2232 Py_END_ALLOW_THREADS
2233 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2234 it got to the end of the directory. */
2235 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2236 Py_DECREF(d);
2237 win32_error("FindNextFile", namebuf);
2238 FindClose(hFindFile);
2239 return NULL;
2240 }
2241 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002242
Victor Stinnerd6f85422010-05-05 23:33:33 +00002243 if (FindClose(hFindFile) == FALSE) {
2244 Py_DECREF(d);
2245 return win32_error("FindClose", namebuf);
2246 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00002247
Victor Stinnerd6f85422010-05-05 23:33:33 +00002248 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002249
Tim Peters0bb44a42000-09-15 07:44:49 +00002250#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251
2252#ifndef MAX_PATH
2253#define MAX_PATH CCHMAXPATH
2254#endif
2255 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00002256 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002257 PyObject *d, *v;
2258 char namebuf[MAX_PATH+5];
2259 HDIR hdir = 1;
2260 ULONG srchcnt = 1;
2261 FILEFINDBUF3 ep;
2262 APIRET rc;
2263
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002264 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002265 return NULL;
2266 if (len >= MAX_PATH) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00002267 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268 return NULL;
2269 }
2270 strcpy(namebuf, name);
2271 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002272 if (*pt == ALTSEP)
2273 *pt = SEP;
2274 if (namebuf[len-1] != SEP)
2275 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276 strcpy(namebuf + len, "*.*");
2277
Victor Stinnerd6f85422010-05-05 23:33:33 +00002278 if ((d = PyList_New(0)) == NULL)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279 return NULL;
2280
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002281 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2282 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002284 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2285 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2286 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287
2288 if (rc != NO_ERROR) {
2289 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00002290 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002291 }
2292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294 do {
2295 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002296 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002297 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002298
2299 strcpy(namebuf, ep.achName);
2300
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002301 /* Leave Case of Name Alone -- In Native Form */
2302 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303
Gregory P. Smithdd96db62008-06-09 04:58:54 +00002304 v = PyString_FromString(namebuf);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002305 if (v == NULL) {
2306 Py_DECREF(d);
2307 d = NULL;
2308 break;
2309 }
2310 if (PyList_Append(d, v) != 0) {
2311 Py_DECREF(v);
2312 Py_DECREF(d);
2313 d = NULL;
2314 break;
2315 }
2316 Py_DECREF(v);
2317 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2318 }
2319
2320 return d;
2321#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002322
Victor Stinnerd6f85422010-05-05 23:33:33 +00002323 char *name = NULL;
2324 PyObject *d, *v;
2325 DIR *dirp;
2326 struct dirent *ep;
2327 int arg_is_unicode = 1;
Just van Rossum96b1c902003-03-03 17:32:15 +00002328
Victor Stinnerd6f85422010-05-05 23:33:33 +00002329 errno = 0;
2330 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2331 arg_is_unicode = 0;
2332 PyErr_Clear();
2333 }
2334 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2335 return NULL;
2336 if ((dirp = opendir(name)) == NULL) {
2337 return posix_error_with_allocated_filename(name);
2338 }
2339 if ((d = PyList_New(0)) == NULL) {
2340 closedir(dirp);
2341 PyMem_Free(name);
2342 return NULL;
2343 }
2344 for (;;) {
2345 errno = 0;
2346 Py_BEGIN_ALLOW_THREADS
2347 ep = readdir(dirp);
2348 Py_END_ALLOW_THREADS
2349 if (ep == NULL) {
2350 if (errno == 0) {
2351 break;
2352 } else {
2353 closedir(dirp);
2354 Py_DECREF(d);
2355 return posix_error_with_allocated_filename(name);
2356 }
2357 }
2358 if (ep->d_name[0] == '.' &&
2359 (NAMLEN(ep) == 1 ||
2360 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2361 continue;
2362 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2363 if (v == NULL) {
2364 Py_DECREF(d);
2365 d = NULL;
2366 break;
2367 }
Just van Rossum46c97842003-02-25 21:42:15 +00002368#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00002369 if (arg_is_unicode) {
2370 PyObject *w;
Just van Rossum46c97842003-02-25 21:42:15 +00002371
Victor Stinnerd6f85422010-05-05 23:33:33 +00002372 w = PyUnicode_FromEncodedObject(v,
2373 Py_FileSystemDefaultEncoding,
2374 "strict");
2375 if (w != NULL) {
2376 Py_DECREF(v);
2377 v = w;
2378 }
2379 else {
2380 /* fall back to the original byte string, as
2381 discussed in patch #683592 */
2382 PyErr_Clear();
2383 }
2384 }
Just van Rossum46c97842003-02-25 21:42:15 +00002385#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002386 if (PyList_Append(d, v) != 0) {
2387 Py_DECREF(v);
2388 Py_DECREF(d);
2389 d = NULL;
2390 break;
2391 }
2392 Py_DECREF(v);
2393 }
2394 closedir(dirp);
2395 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002396
Victor Stinnerd6f85422010-05-05 23:33:33 +00002397 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002398
Tim Peters0bb44a42000-09-15 07:44:49 +00002399#endif /* which OS */
2400} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002401
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002402#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002403/* A helper function for abspath on win32 */
2404static PyObject *
2405posix__getfullpathname(PyObject *self, PyObject *args)
2406{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002407 /* assume encoded strings won't more than double no of chars */
2408 char inbuf[MAX_PATH*2];
2409 char *inbufp = inbuf;
2410 Py_ssize_t insize = sizeof(inbuf);
2411 char outbuf[MAX_PATH*2];
2412 char *temp;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002413
Victor Stinnerd6f85422010-05-05 23:33:33 +00002414 PyUnicodeObject *po;
2415 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2416 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2417 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2418 Py_UNICODE *wtemp;
2419 DWORD result;
2420 PyObject *v;
2421 result = GetFullPathNameW(wpath,
2422 sizeof(woutbuf)/sizeof(woutbuf[0]),
2423 woutbuf, &wtemp);
2424 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2425 woutbufp = malloc(result * sizeof(Py_UNICODE));
2426 if (!woutbufp)
2427 return PyErr_NoMemory();
2428 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2429 }
2430 if (result)
2431 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2432 else
2433 v = win32_error_unicode("GetFullPathNameW", wpath);
2434 if (woutbufp != woutbuf)
2435 free(woutbufp);
2436 return v;
2437 }
2438 /* Drop the argument parsing error as narrow strings
2439 are also valid. */
2440 PyErr_Clear();
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002441
Victor Stinnerd6f85422010-05-05 23:33:33 +00002442 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2443 Py_FileSystemDefaultEncoding, &inbufp,
2444 &insize))
2445 return NULL;
2446 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2447 outbuf, &temp))
2448 return win32_error("GetFullPathName", inbuf);
2449 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2450 return PyUnicode_Decode(outbuf, strlen(outbuf),
2451 Py_FileSystemDefaultEncoding, NULL);
2452 }
2453 return PyString_FromString(outbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002454} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002455#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002456
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002457PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002458"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002459Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002460
Barry Warsaw53699e91996-12-10 23:23:01 +00002461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002462posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002463{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002464 int res;
2465 char *path = NULL;
2466 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002467
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002468#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002469 PyUnicodeObject *po;
2470 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2471 Py_BEGIN_ALLOW_THREADS
2472 /* PyUnicode_AS_UNICODE OK without thread lock as
2473 it is a simple dereference. */
2474 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2475 Py_END_ALLOW_THREADS
2476 if (!res)
2477 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2478 Py_INCREF(Py_None);
2479 return Py_None;
2480 }
2481 /* Drop the argument parsing error as narrow strings
2482 are also valid. */
2483 PyErr_Clear();
2484 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2485 Py_FileSystemDefaultEncoding, &path, &mode))
2486 return NULL;
2487 Py_BEGIN_ALLOW_THREADS
2488 /* PyUnicode_AS_UNICODE OK without thread lock as
2489 it is a simple dereference. */
2490 res = CreateDirectoryA(path, NULL);
2491 Py_END_ALLOW_THREADS
2492 if (!res) {
2493 win32_error("mkdir", path);
2494 PyMem_Free(path);
2495 return NULL;
2496 }
2497 PyMem_Free(path);
2498 Py_INCREF(Py_None);
2499 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002500#else /* MS_WINDOWS */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002501
Victor Stinnerd6f85422010-05-05 23:33:33 +00002502 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2503 Py_FileSystemDefaultEncoding, &path, &mode))
2504 return NULL;
2505 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002506#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002507 res = mkdir(path);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002508#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002509 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002510#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002511 Py_END_ALLOW_THREADS
2512 if (res < 0)
2513 return posix_error_with_allocated_filename(path);
2514 PyMem_Free(path);
2515 Py_INCREF(Py_None);
2516 return Py_None;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002517#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002518}
2519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002520
Neal Norwitz1818ed72006-03-26 00:29:48 +00002521/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2522#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002523#include <sys/resource.h>
2524#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002525
Neal Norwitz1818ed72006-03-26 00:29:48 +00002526
2527#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002528PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002529"nice(inc) -> new_priority\n\n\
2530Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002531
Barry Warsaw53699e91996-12-10 23:23:01 +00002532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002533posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002534{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002535 int increment, value;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002536
Victor Stinnerd6f85422010-05-05 23:33:33 +00002537 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2538 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002539
Victor Stinnerd6f85422010-05-05 23:33:33 +00002540 /* There are two flavours of 'nice': one that returns the new
2541 priority (as required by almost all standards out there) and the
2542 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2543 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002544
Victor Stinnerd6f85422010-05-05 23:33:33 +00002545 If we are of the nice family that returns the new priority, we
2546 need to clear errno before the call, and check if errno is filled
2547 before calling posix_error() on a returnvalue of -1, because the
2548 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002549
Victor Stinnerd6f85422010-05-05 23:33:33 +00002550 errno = 0;
2551 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002552#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002553 if (value == 0)
2554 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002555#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00002556 if (value == -1 && errno != 0)
2557 /* either nice() or getpriority() returned an error */
2558 return posix_error();
2559 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002561#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002563PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002564"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002565Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002566
Barry Warsaw53699e91996-12-10 23:23:01 +00002567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002568posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002569{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002570#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002571 PyObject *o1, *o2;
2572 char *p1, *p2;
2573 BOOL result;
2574 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2575 goto error;
2576 if (!convert_to_unicode(&o1))
2577 goto error;
2578 if (!convert_to_unicode(&o2)) {
2579 Py_DECREF(o1);
2580 goto error;
2581 }
2582 Py_BEGIN_ALLOW_THREADS
2583 result = MoveFileW(PyUnicode_AsUnicode(o1),
2584 PyUnicode_AsUnicode(o2));
2585 Py_END_ALLOW_THREADS
2586 Py_DECREF(o1);
2587 Py_DECREF(o2);
2588 if (!result)
2589 return win32_error("rename", NULL);
2590 Py_INCREF(Py_None);
2591 return Py_None;
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002592error:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002593 PyErr_Clear();
2594 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2595 return NULL;
2596 Py_BEGIN_ALLOW_THREADS
2597 result = MoveFileA(p1, p2);
2598 Py_END_ALLOW_THREADS
2599 if (!result)
2600 return win32_error("rename", NULL);
2601 Py_INCREF(Py_None);
2602 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002603#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002604 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002605#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002606}
2607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002608
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002609PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002610"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002611Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002612
Barry Warsaw53699e91996-12-10 23:23:01 +00002613static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002614posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002615{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002616#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002617 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002618#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002619 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002620#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002621}
2622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002623
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002624PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002625"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002627
Barry Warsaw53699e91996-12-10 23:23:01 +00002628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002629posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002630{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002631#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002632 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002633#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002634 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002635#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002636}
2637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002638
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002639#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002640PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002641"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002642Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002643
Barry Warsaw53699e91996-12-10 23:23:01 +00002644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002645posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002646{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002647 char *command;
2648 long sts;
2649 if (!PyArg_ParseTuple(args, "s:system", &command))
2650 return NULL;
2651 Py_BEGIN_ALLOW_THREADS
2652 sts = system(command);
2653 Py_END_ALLOW_THREADS
2654 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002655}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002656#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002657
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002658
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002660"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002661Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002662
Barry Warsaw53699e91996-12-10 23:23:01 +00002663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002664posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002665{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002666 int i;
2667 if (!PyArg_ParseTuple(args, "i:umask", &i))
2668 return NULL;
2669 i = (int)umask(i);
2670 if (i < 0)
2671 return posix_error();
2672 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002673}
2674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002675
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002679
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002681"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002682Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002683
Barry Warsaw53699e91996-12-10 23:23:01 +00002684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002685posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002686{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002687#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002688 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002689#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002690 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002691#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002692}
2693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002694
Guido van Rossumb6775db1994-08-01 11:34:53 +00002695#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002696PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002697"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002698Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002699
Barry Warsaw53699e91996-12-10 23:23:01 +00002700static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002701posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002702{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002703 struct utsname u;
2704 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002705
Victor Stinnerd6f85422010-05-05 23:33:33 +00002706 Py_BEGIN_ALLOW_THREADS
2707 res = uname(&u);
2708 Py_END_ALLOW_THREADS
2709 if (res < 0)
2710 return posix_error();
2711 return Py_BuildValue("(sssss)",
2712 u.sysname,
2713 u.nodename,
2714 u.release,
2715 u.version,
2716 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002717}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002718#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002719
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002720static int
2721extract_time(PyObject *t, long* sec, long* usec)
2722{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002723 long intval;
2724 if (PyFloat_Check(t)) {
2725 double tval = PyFloat_AsDouble(t);
2726 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2727 if (!intobj)
2728 return -1;
2729 intval = PyInt_AsLong(intobj);
2730 Py_DECREF(intobj);
2731 if (intval == -1 && PyErr_Occurred())
2732 return -1;
2733 *sec = intval;
2734 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2735 if (*usec < 0)
2736 /* If rounding gave us a negative number,
2737 truncate. */
2738 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002739 return 0;
Victor Stinnerd6f85422010-05-05 23:33:33 +00002740 }
2741 intval = PyInt_AsLong(t);
2742 if (intval == -1 && PyErr_Occurred())
2743 return -1;
2744 *sec = intval;
2745 *usec = 0;
2746 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002747}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002749PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002750"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002751utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002752Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002753second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002754
Barry Warsaw53699e91996-12-10 23:23:01 +00002755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002756posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002757{
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002758#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00002759 PyObject *arg;
2760 PyUnicodeObject *obwpath;
2761 wchar_t *wpath = NULL;
2762 char *apath = NULL;
2763 HANDLE hFile;
2764 long atimesec, mtimesec, ausec, musec;
2765 FILETIME atime, mtime;
2766 PyObject *result = NULL;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002767
Victor Stinnerd6f85422010-05-05 23:33:33 +00002768 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2769 wpath = PyUnicode_AS_UNICODE(obwpath);
2770 Py_BEGIN_ALLOW_THREADS
2771 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2772 NULL, OPEN_EXISTING,
2773 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2774 Py_END_ALLOW_THREADS
2775 if (hFile == INVALID_HANDLE_VALUE)
2776 return win32_error_unicode("utime", wpath);
2777 } else
2778 /* Drop the argument parsing error as narrow strings
2779 are also valid. */
2780 PyErr_Clear();
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00002781
Victor Stinnerd6f85422010-05-05 23:33:33 +00002782 if (!wpath) {
2783 if (!PyArg_ParseTuple(args, "etO:utime",
2784 Py_FileSystemDefaultEncoding, &apath, &arg))
2785 return NULL;
2786 Py_BEGIN_ALLOW_THREADS
2787 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2788 NULL, OPEN_EXISTING,
2789 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2790 Py_END_ALLOW_THREADS
2791 if (hFile == INVALID_HANDLE_VALUE) {
2792 win32_error("utime", apath);
2793 PyMem_Free(apath);
2794 return NULL;
2795 }
2796 PyMem_Free(apath);
2797 }
2798
2799 if (arg == Py_None) {
2800 SYSTEMTIME now;
2801 GetSystemTime(&now);
2802 if (!SystemTimeToFileTime(&now, &mtime) ||
2803 !SystemTimeToFileTime(&now, &atime)) {
2804 win32_error("utime", NULL);
2805 goto done;
2806 }
2807 }
2808 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2809 PyErr_SetString(PyExc_TypeError,
2810 "utime() arg 2 must be a tuple (atime, mtime)");
2811 goto done;
2812 }
2813 else {
2814 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2815 &atimesec, &ausec) == -1)
2816 goto done;
2817 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2818 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2819 &mtimesec, &musec) == -1)
2820 goto done;
2821 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2822 }
2823 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2824 /* Avoid putting the file name into the error here,
2825 as that may confuse the user into believing that
2826 something is wrong with the file, when it also
2827 could be the time stamp that gives a problem. */
2828 win32_error("utime", NULL);
2829 }
2830 Py_INCREF(Py_None);
2831 result = Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002832done:
Victor Stinnerd6f85422010-05-05 23:33:33 +00002833 CloseHandle(hFile);
2834 return result;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002835#else /* MS_WINDOWS */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002836
Victor Stinnerd6f85422010-05-05 23:33:33 +00002837 char *path = NULL;
2838 long atime, mtime, ausec, musec;
2839 int res;
2840 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002841
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002842#if defined(HAVE_UTIMES)
Victor Stinnerd6f85422010-05-05 23:33:33 +00002843 struct timeval buf[2];
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002844#define ATIME buf[0].tv_sec
2845#define MTIME buf[1].tv_sec
2846#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002847/* XXX should define struct utimbuf instead, above */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002848 struct utimbuf buf;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002849#define ATIME buf.actime
2850#define MTIME buf.modtime
2851#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002852#else /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002853 time_t buf[2];
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002854#define ATIME buf[0]
2855#define MTIME buf[1]
2856#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002857#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002858
Mark Hammond817c9292003-12-03 01:22:38 +00002859
Victor Stinnerd6f85422010-05-05 23:33:33 +00002860 if (!PyArg_ParseTuple(args, "etO:utime",
2861 Py_FileSystemDefaultEncoding, &path, &arg))
2862 return NULL;
2863 if (arg == Py_None) {
2864 /* optional time values not given */
2865 Py_BEGIN_ALLOW_THREADS
2866 res = utime(path, NULL);
2867 Py_END_ALLOW_THREADS
2868 }
2869 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2870 PyErr_SetString(PyExc_TypeError,
2871 "utime() arg 2 must be a tuple (atime, mtime)");
2872 PyMem_Free(path);
2873 return NULL;
2874 }
2875 else {
2876 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2877 &atime, &ausec) == -1) {
2878 PyMem_Free(path);
2879 return NULL;
2880 }
2881 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2882 &mtime, &musec) == -1) {
2883 PyMem_Free(path);
2884 return NULL;
2885 }
2886 ATIME = atime;
2887 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002888#ifdef HAVE_UTIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00002889 buf[0].tv_usec = ausec;
2890 buf[1].tv_usec = musec;
2891 Py_BEGIN_ALLOW_THREADS
2892 res = utimes(path, buf);
2893 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002894#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00002895 Py_BEGIN_ALLOW_THREADS
2896 res = utime(path, UTIME_ARG);
2897 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002898#endif /* HAVE_UTIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00002899 }
2900 if (res < 0) {
2901 return posix_error_with_allocated_filename(path);
2902 }
2903 PyMem_Free(path);
2904 Py_INCREF(Py_None);
2905 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002906#undef UTIME_ARG
2907#undef ATIME
2908#undef MTIME
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00002909#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002910}
2911
Guido van Rossum85e3b011991-06-03 12:42:10 +00002912
Guido van Rossum3b066191991-06-04 19:40:25 +00002913/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002915PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002916"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002917Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002918
Barry Warsaw53699e91996-12-10 23:23:01 +00002919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002920posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002921{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002922 int sts;
2923 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2924 return NULL;
2925 _exit(sts);
2926 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002927}
2928
Martin v. Löwis114619e2002-10-07 06:44:21 +00002929#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2930static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002931free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002932{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002933 Py_ssize_t i;
2934 for (i = 0; i < count; i++)
2935 PyMem_Free(array[i]);
2936 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002937}
2938#endif
2939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002940
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002941#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002942PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002943"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002944Execute an executable path with arguments, replacing current process.\n\
2945\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00002946 path: path of executable file\n\
2947 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002948
Barry Warsaw53699e91996-12-10 23:23:01 +00002949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002950posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002951{
Victor Stinnerd6f85422010-05-05 23:33:33 +00002952 char *path;
2953 PyObject *argv;
2954 char **argvlist;
2955 Py_ssize_t i, argc;
2956 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002957
Victor Stinnerd6f85422010-05-05 23:33:33 +00002958 /* execv has two arguments: (path, argv), where
2959 argv is a list or tuple of strings. */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002960
Victor Stinnerd6f85422010-05-05 23:33:33 +00002961 if (!PyArg_ParseTuple(args, "etO:execv",
2962 Py_FileSystemDefaultEncoding,
2963 &path, &argv))
2964 return NULL;
2965 if (PyList_Check(argv)) {
2966 argc = PyList_Size(argv);
2967 getitem = PyList_GetItem;
2968 }
2969 else if (PyTuple_Check(argv)) {
2970 argc = PyTuple_Size(argv);
2971 getitem = PyTuple_GetItem;
2972 }
2973 else {
2974 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2975 PyMem_Free(path);
2976 return NULL;
2977 }
2978 if (argc < 1) {
2979 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
2980 PyMem_Free(path);
2981 return NULL;
2982 }
Guido van Rossum50422b42000-04-26 20:34:28 +00002983
Victor Stinnerd6f85422010-05-05 23:33:33 +00002984 argvlist = PyMem_NEW(char *, argc+1);
2985 if (argvlist == NULL) {
2986 PyMem_Free(path);
2987 return PyErr_NoMemory();
2988 }
2989 for (i = 0; i < argc; i++) {
2990 if (!PyArg_Parse((*getitem)(argv, i), "et",
2991 Py_FileSystemDefaultEncoding,
2992 &argvlist[i])) {
2993 free_string_array(argvlist, i);
2994 PyErr_SetString(PyExc_TypeError,
2995 "execv() arg 2 must contain only strings");
2996 PyMem_Free(path);
2997 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002998
Victor Stinnerd6f85422010-05-05 23:33:33 +00002999 }
3000 }
3001 argvlist[argc] = NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003002
Victor Stinnerd6f85422010-05-05 23:33:33 +00003003 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003004
Victor Stinnerd6f85422010-05-05 23:33:33 +00003005 /* If we get here it's definitely an error */
Guido van Rossum85e3b011991-06-03 12:42:10 +00003006
Victor Stinnerd6f85422010-05-05 23:33:33 +00003007 free_string_array(argvlist, argc);
3008 PyMem_Free(path);
3009 return posix_error();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003010}
3011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003012
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003014"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003015Execute a path with arguments and environment, replacing current process.\n\
3016\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003017 path: path of executable file\n\
3018 args: tuple or list of arguments\n\
3019 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003020
Barry Warsaw53699e91996-12-10 23:23:01 +00003021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003022posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003023{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003024 char *path;
3025 PyObject *argv, *env;
3026 char **argvlist;
3027 char **envlist;
3028 PyObject *key, *val, *keys=NULL, *vals=NULL;
3029 Py_ssize_t i, pos, argc, envc;
3030 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3031 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003032
Victor Stinnerd6f85422010-05-05 23:33:33 +00003033 /* execve has three arguments: (path, argv, env), where
3034 argv is a list or tuple of strings and env is a dictionary
3035 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003036
Victor Stinnerd6f85422010-05-05 23:33:33 +00003037 if (!PyArg_ParseTuple(args, "etOO:execve",
3038 Py_FileSystemDefaultEncoding,
3039 &path, &argv, &env))
3040 return NULL;
3041 if (PyList_Check(argv)) {
3042 argc = PyList_Size(argv);
3043 getitem = PyList_GetItem;
3044 }
3045 else if (PyTuple_Check(argv)) {
3046 argc = PyTuple_Size(argv);
3047 getitem = PyTuple_GetItem;
3048 }
3049 else {
3050 PyErr_SetString(PyExc_TypeError,
3051 "execve() arg 2 must be a tuple or list");
3052 goto fail_0;
3053 }
3054 if (!PyMapping_Check(env)) {
3055 PyErr_SetString(PyExc_TypeError,
3056 "execve() arg 3 must be a mapping object");
3057 goto fail_0;
3058 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003059
Victor Stinnerd6f85422010-05-05 23:33:33 +00003060 argvlist = PyMem_NEW(char *, argc+1);
3061 if (argvlist == NULL) {
3062 PyErr_NoMemory();
3063 goto fail_0;
3064 }
3065 for (i = 0; i < argc; i++) {
3066 if (!PyArg_Parse((*getitem)(argv, i),
3067 "et;execve() arg 2 must contain only strings",
3068 Py_FileSystemDefaultEncoding,
3069 &argvlist[i]))
3070 {
3071 lastarg = i;
3072 goto fail_1;
3073 }
3074 }
3075 lastarg = argc;
3076 argvlist[argc] = NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003077
Victor Stinnerd6f85422010-05-05 23:33:33 +00003078 i = PyMapping_Size(env);
3079 if (i < 0)
3080 goto fail_1;
3081 envlist = PyMem_NEW(char *, i + 1);
3082 if (envlist == NULL) {
3083 PyErr_NoMemory();
3084 goto fail_1;
3085 }
3086 envc = 0;
3087 keys = PyMapping_Keys(env);
3088 vals = PyMapping_Values(env);
3089 if (!keys || !vals)
3090 goto fail_2;
3091 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3092 PyErr_SetString(PyExc_TypeError,
3093 "execve(): env.keys() or env.values() is not a list");
3094 goto fail_2;
3095 }
Tim Peters5aa91602002-01-30 05:46:57 +00003096
Victor Stinnerd6f85422010-05-05 23:33:33 +00003097 for (pos = 0; pos < i; pos++) {
3098 char *p, *k, *v;
3099 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00003100
Victor Stinnerd6f85422010-05-05 23:33:33 +00003101 key = PyList_GetItem(keys, pos);
3102 val = PyList_GetItem(vals, pos);
3103 if (!key || !val)
3104 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003105
Victor Stinnerd6f85422010-05-05 23:33:33 +00003106 if (!PyArg_Parse(
3107 key,
3108 "s;execve() arg 3 contains a non-string key",
3109 &k) ||
3110 !PyArg_Parse(
3111 val,
3112 "s;execve() arg 3 contains a non-string value",
3113 &v))
3114 {
3115 goto fail_2;
3116 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003117
3118#if defined(PYOS_OS2)
3119 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3120 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3121#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003122 len = PyString_Size(key) + PyString_Size(val) + 2;
3123 p = PyMem_NEW(char, len);
3124 if (p == NULL) {
3125 PyErr_NoMemory();
3126 goto fail_2;
3127 }
3128 PyOS_snprintf(p, len, "%s=%s", k, v);
3129 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003130#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003131 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003132#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003133 }
3134 envlist[envc] = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003135
Victor Stinnerd6f85422010-05-05 23:33:33 +00003136 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00003137
Victor Stinnerd6f85422010-05-05 23:33:33 +00003138 /* If we get here it's definitely an error */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003139
Victor Stinnerd6f85422010-05-05 23:33:33 +00003140 (void) posix_error();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003141
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003142 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003143 while (--envc >= 0)
3144 PyMem_DEL(envlist[envc]);
3145 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003146 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003147 free_string_array(argvlist, lastarg);
3148 Py_XDECREF(vals);
3149 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003150 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003151 PyMem_Free(path);
3152 return NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003153}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003154#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00003155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003156
Guido van Rossuma1065681999-01-25 23:20:23 +00003157#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003158PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003159"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003160Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003161\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003162 mode: mode of process creation\n\
3163 path: path of executable file\n\
3164 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003165
3166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003167posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003168{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003169 char *path;
3170 PyObject *argv;
3171 char **argvlist;
3172 int mode, i;
3173 Py_ssize_t argc;
3174 Py_intptr_t spawnval;
3175 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00003176
Victor Stinnerd6f85422010-05-05 23:33:33 +00003177 /* spawnv has three arguments: (mode, path, argv), where
3178 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003179
Victor Stinnerd6f85422010-05-05 23:33:33 +00003180 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3181 Py_FileSystemDefaultEncoding,
3182 &path, &argv))
3183 return NULL;
3184 if (PyList_Check(argv)) {
3185 argc = PyList_Size(argv);
3186 getitem = PyList_GetItem;
3187 }
3188 else if (PyTuple_Check(argv)) {
3189 argc = PyTuple_Size(argv);
3190 getitem = PyTuple_GetItem;
3191 }
3192 else {
3193 PyErr_SetString(PyExc_TypeError,
3194 "spawnv() arg 2 must be a tuple or list");
3195 PyMem_Free(path);
3196 return NULL;
3197 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003198
Victor Stinnerd6f85422010-05-05 23:33:33 +00003199 argvlist = PyMem_NEW(char *, argc+1);
3200 if (argvlist == NULL) {
3201 PyMem_Free(path);
3202 return PyErr_NoMemory();
3203 }
3204 for (i = 0; i < argc; i++) {
3205 if (!PyArg_Parse((*getitem)(argv, i), "et",
3206 Py_FileSystemDefaultEncoding,
3207 &argvlist[i])) {
3208 free_string_array(argvlist, i);
3209 PyErr_SetString(
3210 PyExc_TypeError,
3211 "spawnv() arg 2 must contain only strings");
3212 PyMem_Free(path);
3213 return NULL;
3214 }
3215 }
3216 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003217
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003218#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003219 Py_BEGIN_ALLOW_THREADS
3220 spawnval = spawnv(mode, path, argvlist);
3221 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003222#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003223 if (mode == _OLD_P_OVERLAY)
3224 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00003225
Victor Stinnerd6f85422010-05-05 23:33:33 +00003226 Py_BEGIN_ALLOW_THREADS
3227 spawnval = _spawnv(mode, path, argvlist);
3228 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003229#endif
Tim Peters5aa91602002-01-30 05:46:57 +00003230
Victor Stinnerd6f85422010-05-05 23:33:33 +00003231 free_string_array(argvlist, argc);
3232 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003233
Victor Stinnerd6f85422010-05-05 23:33:33 +00003234 if (spawnval == -1)
3235 return posix_error();
3236 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003237#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003238 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003239#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003240 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003241#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003242}
3243
3244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003245PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003246"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00003247Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00003248\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003249 mode: mode of process creation\n\
3250 path: path of executable file\n\
3251 args: tuple or list of arguments\n\
3252 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00003253
3254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003255posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00003256{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003257 char *path;
3258 PyObject *argv, *env;
3259 char **argvlist;
3260 char **envlist;
3261 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3262 int mode, pos, envc;
3263 Py_ssize_t argc, i;
3264 Py_intptr_t spawnval;
3265 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3266 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003267
Victor Stinnerd6f85422010-05-05 23:33:33 +00003268 /* spawnve has four arguments: (mode, path, argv, env), where
3269 argv is a list or tuple of strings and env is a dictionary
3270 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00003271
Victor Stinnerd6f85422010-05-05 23:33:33 +00003272 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3273 Py_FileSystemDefaultEncoding,
3274 &path, &argv, &env))
3275 return NULL;
3276 if (PyList_Check(argv)) {
3277 argc = PyList_Size(argv);
3278 getitem = PyList_GetItem;
3279 }
3280 else if (PyTuple_Check(argv)) {
3281 argc = PyTuple_Size(argv);
3282 getitem = PyTuple_GetItem;
3283 }
3284 else {
3285 PyErr_SetString(PyExc_TypeError,
3286 "spawnve() arg 2 must be a tuple or list");
3287 goto fail_0;
3288 }
3289 if (!PyMapping_Check(env)) {
3290 PyErr_SetString(PyExc_TypeError,
3291 "spawnve() arg 3 must be a mapping object");
3292 goto fail_0;
3293 }
Guido van Rossuma1065681999-01-25 23:20:23 +00003294
Victor Stinnerd6f85422010-05-05 23:33:33 +00003295 argvlist = PyMem_NEW(char *, argc+1);
3296 if (argvlist == NULL) {
3297 PyErr_NoMemory();
3298 goto fail_0;
3299 }
3300 for (i = 0; i < argc; i++) {
3301 if (!PyArg_Parse((*getitem)(argv, i),
3302 "et;spawnve() arg 2 must contain only strings",
3303 Py_FileSystemDefaultEncoding,
3304 &argvlist[i]))
3305 {
3306 lastarg = i;
3307 goto fail_1;
3308 }
3309 }
3310 lastarg = argc;
3311 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00003312
Victor Stinnerd6f85422010-05-05 23:33:33 +00003313 i = PyMapping_Size(env);
3314 if (i < 0)
3315 goto fail_1;
3316 envlist = PyMem_NEW(char *, i + 1);
3317 if (envlist == NULL) {
3318 PyErr_NoMemory();
3319 goto fail_1;
3320 }
3321 envc = 0;
3322 keys = PyMapping_Keys(env);
3323 vals = PyMapping_Values(env);
3324 if (!keys || !vals)
3325 goto fail_2;
3326 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3327 PyErr_SetString(PyExc_TypeError,
3328 "spawnve(): env.keys() or env.values() is not a list");
3329 goto fail_2;
3330 }
Tim Peters5aa91602002-01-30 05:46:57 +00003331
Victor Stinnerd6f85422010-05-05 23:33:33 +00003332 for (pos = 0; pos < i; pos++) {
3333 char *p, *k, *v;
3334 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003335
Victor Stinnerd6f85422010-05-05 23:33:33 +00003336 key = PyList_GetItem(keys, pos);
3337 val = PyList_GetItem(vals, pos);
3338 if (!key || !val)
3339 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003340
Victor Stinnerd6f85422010-05-05 23:33:33 +00003341 if (!PyArg_Parse(
3342 key,
3343 "s;spawnve() arg 3 contains a non-string key",
3344 &k) ||
3345 !PyArg_Parse(
3346 val,
3347 "s;spawnve() arg 3 contains a non-string value",
3348 &v))
3349 {
3350 goto fail_2;
3351 }
3352 len = PyString_Size(key) + PyString_Size(val) + 2;
3353 p = PyMem_NEW(char, len);
3354 if (p == NULL) {
3355 PyErr_NoMemory();
3356 goto fail_2;
3357 }
3358 PyOS_snprintf(p, len, "%s=%s", k, v);
3359 envlist[envc++] = p;
3360 }
3361 envlist[envc] = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00003362
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003363#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003364 Py_BEGIN_ALLOW_THREADS
3365 spawnval = spawnve(mode, path, argvlist, envlist);
3366 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003367#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003368 if (mode == _OLD_P_OVERLAY)
3369 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003370
Victor Stinnerd6f85422010-05-05 23:33:33 +00003371 Py_BEGIN_ALLOW_THREADS
3372 spawnval = _spawnve(mode, path, argvlist, envlist);
3373 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003374#endif
Tim Peters25059d32001-12-07 20:35:43 +00003375
Victor Stinnerd6f85422010-05-05 23:33:33 +00003376 if (spawnval == -1)
3377 (void) posix_error();
3378 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003379#if SIZEOF_LONG == SIZEOF_VOID_P
Victor Stinnerd6f85422010-05-05 23:33:33 +00003380 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003381#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003382 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003383#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003384
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003385 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003386 while (--envc >= 0)
3387 PyMem_DEL(envlist[envc]);
3388 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003389 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003390 free_string_array(argvlist, lastarg);
3391 Py_XDECREF(vals);
3392 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003393 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003394 PyMem_Free(path);
3395 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00003396}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003397
3398/* OS/2 supports spawnvp & spawnvpe natively */
3399#if defined(PYOS_OS2)
3400PyDoc_STRVAR(posix_spawnvp__doc__,
3401"spawnvp(mode, file, args)\n\n\
3402Execute the program 'file' in a new process, using the environment\n\
3403search path to find the file.\n\
3404\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003405 mode: mode of process creation\n\
3406 file: executable file name\n\
3407 args: tuple or list of strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003408
3409static PyObject *
3410posix_spawnvp(PyObject *self, PyObject *args)
3411{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003412 char *path;
3413 PyObject *argv;
3414 char **argvlist;
3415 int mode, i, argc;
3416 Py_intptr_t spawnval;
3417 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003418
Victor Stinnerd6f85422010-05-05 23:33:33 +00003419 /* spawnvp has three arguments: (mode, path, argv), where
3420 argv is a list or tuple of strings. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003421
Victor Stinnerd6f85422010-05-05 23:33:33 +00003422 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3423 Py_FileSystemDefaultEncoding,
3424 &path, &argv))
3425 return NULL;
3426 if (PyList_Check(argv)) {
3427 argc = PyList_Size(argv);
3428 getitem = PyList_GetItem;
3429 }
3430 else if (PyTuple_Check(argv)) {
3431 argc = PyTuple_Size(argv);
3432 getitem = PyTuple_GetItem;
3433 }
3434 else {
3435 PyErr_SetString(PyExc_TypeError,
3436 "spawnvp() arg 2 must be a tuple or list");
3437 PyMem_Free(path);
3438 return NULL;
3439 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003440
Victor Stinnerd6f85422010-05-05 23:33:33 +00003441 argvlist = PyMem_NEW(char *, argc+1);
3442 if (argvlist == NULL) {
3443 PyMem_Free(path);
3444 return PyErr_NoMemory();
3445 }
3446 for (i = 0; i < argc; i++) {
3447 if (!PyArg_Parse((*getitem)(argv, i), "et",
3448 Py_FileSystemDefaultEncoding,
3449 &argvlist[i])) {
3450 free_string_array(argvlist, i);
3451 PyErr_SetString(
3452 PyExc_TypeError,
3453 "spawnvp() arg 2 must contain only strings");
3454 PyMem_Free(path);
3455 return NULL;
3456 }
3457 }
3458 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003459
Victor Stinnerd6f85422010-05-05 23:33:33 +00003460 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003461#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003462 spawnval = spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003463#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003464 spawnval = _spawnvp(mode, path, argvlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003465#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003466 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003467
Victor Stinnerd6f85422010-05-05 23:33:33 +00003468 free_string_array(argvlist, argc);
3469 PyMem_Free(path);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003470
Victor Stinnerd6f85422010-05-05 23:33:33 +00003471 if (spawnval == -1)
3472 return posix_error();
3473 else
3474 return Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003475}
3476
3477
3478PyDoc_STRVAR(posix_spawnvpe__doc__,
3479"spawnvpe(mode, file, args, env)\n\n\
3480Execute the program 'file' in a new process, using the environment\n\
3481search path to find the file.\n\
3482\n\
Victor Stinnerd6f85422010-05-05 23:33:33 +00003483 mode: mode of process creation\n\
3484 file: executable file name\n\
3485 args: tuple or list of arguments\n\
3486 env: dictionary of strings mapping to strings");
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003487
3488static PyObject *
3489posix_spawnvpe(PyObject *self, PyObject *args)
3490{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003491 char *path;
3492 PyObject *argv, *env;
3493 char **argvlist;
3494 char **envlist;
3495 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3496 int mode, i, pos, argc, envc;
3497 Py_intptr_t spawnval;
3498 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3499 int lastarg = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003500
Victor Stinnerd6f85422010-05-05 23:33:33 +00003501 /* spawnvpe has four arguments: (mode, path, argv, env), where
3502 argv is a list or tuple of strings and env is a dictionary
3503 like posix.environ. */
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003504
Victor Stinnerd6f85422010-05-05 23:33:33 +00003505 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3506 Py_FileSystemDefaultEncoding,
3507 &path, &argv, &env))
3508 return NULL;
3509 if (PyList_Check(argv)) {
3510 argc = PyList_Size(argv);
3511 getitem = PyList_GetItem;
3512 }
3513 else if (PyTuple_Check(argv)) {
3514 argc = PyTuple_Size(argv);
3515 getitem = PyTuple_GetItem;
3516 }
3517 else {
3518 PyErr_SetString(PyExc_TypeError,
3519 "spawnvpe() arg 2 must be a tuple or list");
3520 goto fail_0;
3521 }
3522 if (!PyMapping_Check(env)) {
3523 PyErr_SetString(PyExc_TypeError,
3524 "spawnvpe() arg 3 must be a mapping object");
3525 goto fail_0;
3526 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003527
Victor Stinnerd6f85422010-05-05 23:33:33 +00003528 argvlist = PyMem_NEW(char *, argc+1);
3529 if (argvlist == NULL) {
3530 PyErr_NoMemory();
3531 goto fail_0;
3532 }
3533 for (i = 0; i < argc; i++) {
3534 if (!PyArg_Parse((*getitem)(argv, i),
3535 "et;spawnvpe() arg 2 must contain only strings",
3536 Py_FileSystemDefaultEncoding,
3537 &argvlist[i]))
3538 {
3539 lastarg = i;
3540 goto fail_1;
3541 }
3542 }
3543 lastarg = argc;
3544 argvlist[argc] = NULL;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003545
Victor Stinnerd6f85422010-05-05 23:33:33 +00003546 i = PyMapping_Size(env);
3547 if (i < 0)
3548 goto fail_1;
3549 envlist = PyMem_NEW(char *, i + 1);
3550 if (envlist == NULL) {
3551 PyErr_NoMemory();
3552 goto fail_1;
3553 }
3554 envc = 0;
3555 keys = PyMapping_Keys(env);
3556 vals = PyMapping_Values(env);
3557 if (!keys || !vals)
3558 goto fail_2;
3559 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3560 PyErr_SetString(PyExc_TypeError,
3561 "spawnvpe(): env.keys() or env.values() is not a list");
3562 goto fail_2;
3563 }
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003564
Victor Stinnerd6f85422010-05-05 23:33:33 +00003565 for (pos = 0; pos < i; pos++) {
3566 char *p, *k, *v;
3567 size_t len;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003568
Victor Stinnerd6f85422010-05-05 23:33:33 +00003569 key = PyList_GetItem(keys, pos);
3570 val = PyList_GetItem(vals, pos);
3571 if (!key || !val)
3572 goto fail_2;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003573
Victor Stinnerd6f85422010-05-05 23:33:33 +00003574 if (!PyArg_Parse(
3575 key,
3576 "s;spawnvpe() arg 3 contains a non-string key",
3577 &k) ||
3578 !PyArg_Parse(
3579 val,
3580 "s;spawnvpe() arg 3 contains a non-string value",
3581 &v))
3582 {
3583 goto fail_2;
3584 }
3585 len = PyString_Size(key) + PyString_Size(val) + 2;
3586 p = PyMem_NEW(char, len);
3587 if (p == NULL) {
3588 PyErr_NoMemory();
3589 goto fail_2;
3590 }
3591 PyOS_snprintf(p, len, "%s=%s", k, v);
3592 envlist[envc++] = p;
3593 }
3594 envlist[envc] = 0;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003595
Victor Stinnerd6f85422010-05-05 23:33:33 +00003596 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003597#if defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003598 spawnval = spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003599#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003600 spawnval = _spawnvpe(mode, path, argvlist, envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003601#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003602 Py_END_ALLOW_THREADS
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003603
Victor Stinnerd6f85422010-05-05 23:33:33 +00003604 if (spawnval == -1)
3605 (void) posix_error();
3606 else
3607 res = Py_BuildValue("l", (long) spawnval);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003608
3609 fail_2:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003610 while (--envc >= 0)
3611 PyMem_DEL(envlist[envc]);
3612 PyMem_DEL(envlist);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003613 fail_1:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003614 free_string_array(argvlist, lastarg);
3615 Py_XDECREF(vals);
3616 Py_XDECREF(keys);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003617 fail_0:
Victor Stinnerd6f85422010-05-05 23:33:33 +00003618 PyMem_Free(path);
3619 return res;
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003620}
3621#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003622#endif /* HAVE_SPAWNV */
3623
3624
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003625#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003626PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003627"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003628Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3629\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003630Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003631
3632static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003633posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003634{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003635 pid_t pid;
3636 int result = 0;
3637 _PyImport_AcquireLock();
3638 pid = fork1();
3639 if (pid == 0) {
3640 /* child: this clobbers and resets the import lock. */
3641 PyOS_AfterFork();
3642 } else {
3643 /* parent: release the import lock. */
3644 result = _PyImport_ReleaseLock();
3645 }
3646 if (pid == -1)
3647 return posix_error();
3648 if (result < 0) {
3649 /* Don't clobber the OSError if the fork failed. */
3650 PyErr_SetString(PyExc_RuntimeError,
3651 "not holding the import lock");
3652 return NULL;
3653 }
3654 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003655}
3656#endif
3657
3658
Guido van Rossumad0ee831995-03-01 10:34:45 +00003659#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003660PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003661"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003662Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003663Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003664
Barry Warsaw53699e91996-12-10 23:23:01 +00003665static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003666posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003667{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003668 pid_t pid;
3669 int result = 0;
3670 _PyImport_AcquireLock();
3671 pid = fork();
3672 if (pid == 0) {
3673 /* child: this clobbers and resets the import lock. */
3674 PyOS_AfterFork();
3675 } else {
3676 /* parent: release the import lock. */
3677 result = _PyImport_ReleaseLock();
3678 }
3679 if (pid == -1)
3680 return posix_error();
3681 if (result < 0) {
3682 /* Don't clobber the OSError if the fork failed. */
3683 PyErr_SetString(PyExc_RuntimeError,
3684 "not holding the import lock");
3685 return NULL;
3686 }
3687 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003688}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003689#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003690
Neal Norwitzb59798b2003-03-21 01:43:31 +00003691/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003692/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3693#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003694#define DEV_PTY_FILE "/dev/ptc"
3695#define HAVE_DEV_PTMX
3696#else
3697#define DEV_PTY_FILE "/dev/ptmx"
3698#endif
3699
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003700#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003701#ifdef HAVE_PTY_H
3702#include <pty.h>
3703#else
3704#ifdef HAVE_LIBUTIL_H
3705#include <libutil.h>
Ronald Oussorena55af9a2010-01-17 16:25:57 +00003706#else
3707#ifdef HAVE_UTIL_H
3708#include <util.h>
3709#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003710#endif /* HAVE_LIBUTIL_H */
3711#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003712#ifdef HAVE_STROPTS_H
3713#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003714#endif
3715#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003716
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003717#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003718PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003719"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003720Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003721
3722static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003723posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003724{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003725 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003726#ifndef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003727 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003728#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003729#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003730 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003731#ifdef sun
Victor Stinnerd6f85422010-05-05 23:33:33 +00003732 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003733#endif
3734#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003735
Thomas Wouters70c21a12000-07-14 14:28:33 +00003736#ifdef HAVE_OPENPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00003737 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3738 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003739#elif defined(HAVE__GETPTY)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003740 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3741 if (slave_name == NULL)
3742 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00003743
Victor Stinnerd6f85422010-05-05 23:33:33 +00003744 slave_fd = open(slave_name, O_RDWR);
3745 if (slave_fd < 0)
3746 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003747#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003748 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3749 if (master_fd < 0)
3750 return posix_error();
3751 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3752 /* change permission of slave */
3753 if (grantpt(master_fd) < 0) {
3754 PyOS_setsig(SIGCHLD, sig_saved);
3755 return posix_error();
3756 }
3757 /* unlock slave */
3758 if (unlockpt(master_fd) < 0) {
3759 PyOS_setsig(SIGCHLD, sig_saved);
3760 return posix_error();
3761 }
3762 PyOS_setsig(SIGCHLD, sig_saved);
3763 slave_name = ptsname(master_fd); /* get name of slave */
3764 if (slave_name == NULL)
3765 return posix_error();
3766 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3767 if (slave_fd < 0)
3768 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003769#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00003770 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3771 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003772#ifndef __hpux
Victor Stinnerd6f85422010-05-05 23:33:33 +00003773 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003774#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003775#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003776#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003777
Victor Stinnerd6f85422010-05-05 23:33:33 +00003778 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003779
Fred Drake8cef4cf2000-06-28 16:40:38 +00003780}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003781#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003782
3783#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003784PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003785"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003786Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3787Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003788To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003789
3790static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003791posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003792{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003793 int master_fd = -1, result = 0;
3794 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003795
Victor Stinnerd6f85422010-05-05 23:33:33 +00003796 _PyImport_AcquireLock();
3797 pid = forkpty(&master_fd, NULL, NULL, NULL);
3798 if (pid == 0) {
3799 /* child: this clobbers and resets the import lock. */
3800 PyOS_AfterFork();
3801 } else {
3802 /* parent: release the import lock. */
3803 result = _PyImport_ReleaseLock();
3804 }
3805 if (pid == -1)
3806 return posix_error();
3807 if (result < 0) {
3808 /* Don't clobber the OSError if the fork failed. */
3809 PyErr_SetString(PyExc_RuntimeError,
3810 "not holding the import lock");
3811 return NULL;
3812 }
3813 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00003814}
3815#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003816
Guido van Rossumad0ee831995-03-01 10:34:45 +00003817#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003818PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003819"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003821
Barry Warsaw53699e91996-12-10 23:23:01 +00003822static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003823posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003824{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003825 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003826}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003827#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003828
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003829
Guido van Rossumad0ee831995-03-01 10:34:45 +00003830#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003831PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003832"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003833Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003834
Barry Warsaw53699e91996-12-10 23:23:01 +00003835static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003836posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003837{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003838 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003839}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003840#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842
Guido van Rossumad0ee831995-03-01 10:34:45 +00003843#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003844PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003845"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003846Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003847
Barry Warsaw53699e91996-12-10 23:23:01 +00003848static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003849posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003850{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003851 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003852}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003853#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003856PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003857"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003858Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003859
Barry Warsaw53699e91996-12-10 23:23:01 +00003860static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003861posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003862{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003863 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003864}
3865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003866
Fred Drakec9680921999-12-13 16:37:25 +00003867#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003868PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003869"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003870Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003871
3872static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003873posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003874{
3875 PyObject *result = NULL;
3876
Fred Drakec9680921999-12-13 16:37:25 +00003877#ifdef NGROUPS_MAX
3878#define MAX_GROUPS NGROUPS_MAX
3879#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00003880 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00003881#define MAX_GROUPS 64
3882#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00003883 gid_t grouplist[MAX_GROUPS];
3884 int n;
Fred Drakec9680921999-12-13 16:37:25 +00003885
Victor Stinnerd6f85422010-05-05 23:33:33 +00003886 n = getgroups(MAX_GROUPS, grouplist);
3887 if (n < 0)
3888 posix_error();
3889 else {
3890 result = PyList_New(n);
3891 if (result != NULL) {
3892 int i;
3893 for (i = 0; i < n; ++i) {
3894 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3895 if (o == NULL) {
3896 Py_DECREF(result);
3897 result = NULL;
3898 break;
Fred Drakec9680921999-12-13 16:37:25 +00003899 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003900 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00003901 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00003902 }
3903 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003904
Fred Drakec9680921999-12-13 16:37:25 +00003905 return result;
3906}
3907#endif
3908
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003909#ifdef HAVE_INITGROUPS
3910PyDoc_STRVAR(posix_initgroups__doc__,
3911"initgroups(username, gid) -> None\n\n\
3912Call the system initgroups() to initialize the group access list with all of\n\
3913the groups of which the specified username is a member, plus the specified\n\
3914group id.");
3915
3916static PyObject *
3917posix_initgroups(PyObject *self, PyObject *args)
3918{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003919 char *username;
3920 long gid;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003921
Victor Stinnerd6f85422010-05-05 23:33:33 +00003922 if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
3923 return NULL;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003924
Victor Stinnerd6f85422010-05-05 23:33:33 +00003925 if (initgroups(username, (gid_t) gid) == -1)
3926 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003927
Victor Stinnerd6f85422010-05-05 23:33:33 +00003928 Py_INCREF(Py_None);
3929 return Py_None;
Antoine Pitrou30b3b352009-12-02 20:37:54 +00003930}
3931#endif
3932
Martin v. Löwis606edc12002-06-13 21:09:11 +00003933#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003934PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003935"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003936Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003937
3938static PyObject *
3939posix_getpgid(PyObject *self, PyObject *args)
3940{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003941 pid_t pid, pgid;
3942 if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
3943 return NULL;
3944 pgid = getpgid(pid);
3945 if (pgid < 0)
3946 return posix_error();
3947 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00003948}
3949#endif /* HAVE_GETPGID */
3950
3951
Guido van Rossumb6775db1994-08-01 11:34:53 +00003952#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003953PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003954"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003956
Barry Warsaw53699e91996-12-10 23:23:01 +00003957static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003958posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003959{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003960#ifdef GETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00003961 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003962#else /* GETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003963 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003964#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003965}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003966#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003967
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003968
Guido van Rossumb6775db1994-08-01 11:34:53 +00003969#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003970PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003971"setpgrp()\n\n\
Senthil Kumaran0d6908b2010-06-17 16:38:34 +00003972Make this process the process group leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003973
Barry Warsaw53699e91996-12-10 23:23:01 +00003974static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003975posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003976{
Guido van Rossum64933891994-10-20 21:56:42 +00003977#ifdef SETPGRP_HAVE_ARG
Victor Stinnerd6f85422010-05-05 23:33:33 +00003978 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003979#else /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003980 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003981#endif /* SETPGRP_HAVE_ARG */
Victor Stinnerd6f85422010-05-05 23:33:33 +00003982 return posix_error();
3983 Py_INCREF(Py_None);
3984 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003985}
3986
Guido van Rossumb6775db1994-08-01 11:34:53 +00003987#endif /* HAVE_SETPGRP */
3988
Guido van Rossumad0ee831995-03-01 10:34:45 +00003989#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003991"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003992Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993
Barry Warsaw53699e91996-12-10 23:23:01 +00003994static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003995posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003996{
Victor Stinnerd6f85422010-05-05 23:33:33 +00003997 return PyLong_FromPid(getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003998}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003999#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004001
Fred Drake12c6e2d1999-12-14 21:25:03 +00004002#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004003PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004004"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004005Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00004006
4007static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004008posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004009{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004010 PyObject *result = NULL;
4011 char *name;
4012 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004013
Victor Stinnerd6f85422010-05-05 23:33:33 +00004014 errno = 0;
4015 name = getlogin();
4016 if (name == NULL) {
4017 if (errno)
4018 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00004019 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004020 PyErr_SetString(PyExc_OSError,
4021 "unable to determine login name");
4022 }
4023 else
4024 result = PyString_FromString(name);
4025 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00004026
Fred Drake12c6e2d1999-12-14 21:25:03 +00004027 return result;
4028}
4029#endif
4030
Guido van Rossumad0ee831995-03-01 10:34:45 +00004031#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004032PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004033"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004034Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004035
Barry Warsaw53699e91996-12-10 23:23:01 +00004036static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004037posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00004038{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004039 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00004040}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004041#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00004042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004043
Guido van Rossumad0ee831995-03-01 10:34:45 +00004044#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004045PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004046"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004047Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004048
Barry Warsaw53699e91996-12-10 23:23:01 +00004049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004050posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004051{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004052 pid_t pid;
4053 int sig;
4054 if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
4055 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004056#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004057 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
4058 APIRET rc;
4059 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004060 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004061
4062 } else if (sig == XCPT_SIGNAL_KILLPROC) {
4063 APIRET rc;
4064 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004065 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004066
4067 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00004068 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004069#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00004070 if (kill(pid, sig) == -1)
4071 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004072#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004073 Py_INCREF(Py_None);
4074 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004076#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004077
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004078#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004079PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004080"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004081Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004082
4083static PyObject *
4084posix_killpg(PyObject *self, PyObject *args)
4085{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004086 int sig;
4087 pid_t pgid;
4088 /* XXX some man pages make the `pgid` parameter an int, others
4089 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
4090 take the same type. Moreover, pid_t is always at least as wide as
4091 int (else compilation of this module fails), which is safe. */
4092 if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
4093 return NULL;
4094 if (killpg(pgid, sig) == -1)
4095 return posix_error();
4096 Py_INCREF(Py_None);
4097 return Py_None;
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00004098}
4099#endif
4100
Brian Curtine5aa8862010-04-02 23:26:06 +00004101#ifdef MS_WINDOWS
4102PyDoc_STRVAR(win32_kill__doc__,
4103"kill(pid, sig)\n\n\
4104Kill a process with a signal.");
4105
4106static PyObject *
4107win32_kill(PyObject *self, PyObject *args)
4108{
Amaury Forgeot d'Arc03acec22010-05-15 21:45:30 +00004109 PyObject *result;
Victor Stinnerd6f85422010-05-05 23:33:33 +00004110 DWORD pid, sig, err;
4111 HANDLE handle;
Brian Curtine5aa8862010-04-02 23:26:06 +00004112
Victor Stinnerd6f85422010-05-05 23:33:33 +00004113 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig))
4114 return NULL;
Brian Curtine5aa8862010-04-02 23:26:06 +00004115
Victor Stinnerd6f85422010-05-05 23:33:33 +00004116 /* Console processes which share a common console can be sent CTRL+C or
4117 CTRL+BREAK events, provided they handle said events. */
4118 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
4119 if (GenerateConsoleCtrlEvent(sig, pid) == 0) {
4120 err = GetLastError();
4121 return PyErr_SetFromWindowsErr(err);
4122 }
4123 else
4124 Py_RETURN_NONE;
4125 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004126
Victor Stinnerd6f85422010-05-05 23:33:33 +00004127 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
4128 attempt to open and terminate the process. */
4129 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
4130 if (handle == NULL) {
4131 err = GetLastError();
4132 return PyErr_SetFromWindowsErr(err);
4133 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004134
Victor Stinnerd6f85422010-05-05 23:33:33 +00004135 if (TerminateProcess(handle, sig) == 0) {
4136 err = GetLastError();
4137 result = PyErr_SetFromWindowsErr(err);
4138 } else {
4139 Py_INCREF(Py_None);
4140 result = Py_None;
4141 }
Brian Curtine5aa8862010-04-02 23:26:06 +00004142
Victor Stinnerd6f85422010-05-05 23:33:33 +00004143 CloseHandle(handle);
4144 return result;
Brian Curtine5aa8862010-04-02 23:26:06 +00004145}
4146#endif /* MS_WINDOWS */
4147
Guido van Rossumc0125471996-06-28 18:55:32 +00004148#ifdef HAVE_PLOCK
4149
4150#ifdef HAVE_SYS_LOCK_H
4151#include <sys/lock.h>
4152#endif
4153
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Barry Warsaw53699e91996-12-10 23:23:01 +00004158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004159posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00004160{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004161 int op;
4162 if (!PyArg_ParseTuple(args, "i:plock", &op))
4163 return NULL;
4164 if (plock(op) == -1)
4165 return posix_error();
4166 Py_INCREF(Py_None);
4167 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00004168}
4169#endif
4170
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004171
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004172#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004173PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004174"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004175Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004176
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004177#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004178#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004179static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004180async_system(const char *command)
4181{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004182 char errormsg[256], args[1024];
4183 RESULTCODES rcodes;
4184 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004185
Victor Stinnerd6f85422010-05-05 23:33:33 +00004186 char *shell = getenv("COMSPEC");
4187 if (!shell)
4188 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004189
Victor Stinnerd6f85422010-05-05 23:33:33 +00004190 /* avoid overflowing the argument buffer */
4191 if (strlen(shell) + 3 + strlen(command) >= 1024)
4192 return ERROR_NOT_ENOUGH_MEMORY
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004193
Victor Stinnerd6f85422010-05-05 23:33:33 +00004194 args[0] = '\0';
4195 strcat(args, shell);
4196 strcat(args, "/c ");
4197 strcat(args, command);
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00004198
Victor Stinnerd6f85422010-05-05 23:33:33 +00004199 /* execute asynchronously, inheriting the environment */
4200 rc = DosExecPgm(errormsg,
4201 sizeof(errormsg),
4202 EXEC_ASYNC,
4203 args,
4204 NULL,
4205 &rcodes,
4206 shell);
4207 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004208}
4209
Guido van Rossumd48f2521997-12-05 22:19:34 +00004210static FILE *
4211popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004212{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004213 int oldfd, tgtfd;
4214 HFILE pipeh[2];
4215 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004216
Victor Stinnerd6f85422010-05-05 23:33:33 +00004217 /* mode determines which of stdin or stdout is reconnected to
4218 * the pipe to the child
4219 */
4220 if (strchr(mode, 'r') != NULL) {
4221 tgt_fd = 1; /* stdout */
4222 } else if (strchr(mode, 'w')) {
4223 tgt_fd = 0; /* stdin */
4224 } else {
4225 *err = ERROR_INVALID_ACCESS;
4226 return NULL;
4227 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004228
Victor Stinnerd6f85422010-05-05 23:33:33 +00004229 /* setup the pipe */
4230 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4231 *err = rc;
4232 return NULL;
4233 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004234
Victor Stinnerd6f85422010-05-05 23:33:33 +00004235 /* prevent other threads accessing stdio */
4236 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004237
Victor Stinnerd6f85422010-05-05 23:33:33 +00004238 /* reconnect stdio and execute child */
4239 oldfd = dup(tgtfd);
4240 close(tgtfd);
4241 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4242 DosClose(pipeh[tgtfd]);
4243 rc = async_system(command);
4244 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004245
Victor Stinnerd6f85422010-05-05 23:33:33 +00004246 /* restore stdio */
4247 dup2(oldfd, tgtfd);
4248 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004249
Victor Stinnerd6f85422010-05-05 23:33:33 +00004250 /* allow other threads access to stdio */
4251 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004252
Victor Stinnerd6f85422010-05-05 23:33:33 +00004253 /* if execution of child was successful return file stream */
4254 if (rc == NO_ERROR)
4255 return fdopen(pipeh[1 - tgtfd], mode);
4256 else {
4257 DosClose(pipeh[1 - tgtfd]);
4258 *err = rc;
4259 return NULL;
4260 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004261}
4262
4263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004264posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004265{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004266 char *name;
4267 char *mode = "r";
4268 int err, bufsize = -1;
4269 FILE *fp;
4270 PyObject *f;
4271 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4272 return NULL;
4273 Py_BEGIN_ALLOW_THREADS
4274 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4275 Py_END_ALLOW_THREADS
4276 if (fp == NULL)
4277 return os2_error(err);
Guido van Rossumd48f2521997-12-05 22:19:34 +00004278
Victor Stinnerd6f85422010-05-05 23:33:33 +00004279 f = PyFile_FromFile(fp, name, mode, fclose);
4280 if (f != NULL)
4281 PyFile_SetBufSize(f, bufsize);
4282 return f;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004283}
4284
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004285#elif defined(PYCC_GCC)
4286
4287/* standard posix version of popen() support */
4288static PyObject *
4289posix_popen(PyObject *self, PyObject *args)
4290{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004291 char *name;
4292 char *mode = "r";
4293 int bufsize = -1;
4294 FILE *fp;
4295 PyObject *f;
4296 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4297 return NULL;
4298 Py_BEGIN_ALLOW_THREADS
4299 fp = popen(name, mode);
4300 Py_END_ALLOW_THREADS
4301 if (fp == NULL)
4302 return posix_error();
4303 f = PyFile_FromFile(fp, name, mode, pclose);
4304 if (f != NULL)
4305 PyFile_SetBufSize(f, bufsize);
4306 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004307}
4308
4309/* fork() under OS/2 has lots'o'warts
4310 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4311 * most of this code is a ripoff of the win32 code, but using the
4312 * capabilities of EMX's C library routines
4313 */
4314
4315/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4316#define POPEN_1 1
4317#define POPEN_2 2
4318#define POPEN_3 3
4319#define POPEN_4 4
4320
4321static PyObject *_PyPopen(char *, int, int, int);
4322static int _PyPclose(FILE *file);
4323
4324/*
4325 * Internal dictionary mapping popen* file pointers to process handles,
4326 * for use when retrieving the process exit code. See _PyPclose() below
4327 * for more information on this dictionary's use.
4328 */
4329static PyObject *_PyPopenProcs = NULL;
4330
4331/* os2emx version of popen2()
4332 *
4333 * The result of this function is a pipe (file) connected to the
4334 * process's stdin, and a pipe connected to the process's stdout.
4335 */
4336
4337static PyObject *
4338os2emx_popen2(PyObject *self, PyObject *args)
4339{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004340 PyObject *f;
4341 int tm=0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004342
Victor Stinnerd6f85422010-05-05 23:33:33 +00004343 char *cmdstring;
4344 char *mode = "t";
4345 int bufsize = -1;
4346 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4347 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004348
Victor Stinnerd6f85422010-05-05 23:33:33 +00004349 if (*mode == 't')
4350 tm = O_TEXT;
4351 else if (*mode != 'b') {
4352 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4353 return NULL;
4354 } else
4355 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004356
Victor Stinnerd6f85422010-05-05 23:33:33 +00004357 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004358
Victor Stinnerd6f85422010-05-05 23:33:33 +00004359 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004360}
4361
4362/*
4363 * Variation on os2emx.popen2
4364 *
4365 * The result of this function is 3 pipes - the process's stdin,
4366 * stdout and stderr
4367 */
4368
4369static PyObject *
4370os2emx_popen3(PyObject *self, PyObject *args)
4371{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004372 PyObject *f;
4373 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004374
Victor Stinnerd6f85422010-05-05 23:33:33 +00004375 char *cmdstring;
4376 char *mode = "t";
4377 int bufsize = -1;
4378 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4379 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004380
Victor Stinnerd6f85422010-05-05 23:33:33 +00004381 if (*mode == 't')
4382 tm = O_TEXT;
4383 else if (*mode != 'b') {
4384 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4385 return NULL;
4386 } else
4387 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004388
Victor Stinnerd6f85422010-05-05 23:33:33 +00004389 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004390
Victor Stinnerd6f85422010-05-05 23:33:33 +00004391 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004392}
4393
4394/*
4395 * Variation on os2emx.popen2
4396 *
Tim Peters11b23062003-04-23 02:39:17 +00004397 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004398 * and stdout+stderr combined as a single pipe.
4399 */
4400
4401static PyObject *
4402os2emx_popen4(PyObject *self, PyObject *args)
4403{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004404 PyObject *f;
4405 int tm = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004406
Victor Stinnerd6f85422010-05-05 23:33:33 +00004407 char *cmdstring;
4408 char *mode = "t";
4409 int bufsize = -1;
4410 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4411 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004412
Victor Stinnerd6f85422010-05-05 23:33:33 +00004413 if (*mode == 't')
4414 tm = O_TEXT;
4415 else if (*mode != 'b') {
4416 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4417 return NULL;
4418 } else
4419 tm = O_BINARY;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004420
Victor Stinnerd6f85422010-05-05 23:33:33 +00004421 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004422
Victor Stinnerd6f85422010-05-05 23:33:33 +00004423 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004424}
4425
4426/* a couple of structures for convenient handling of multiple
4427 * file handles and pipes
4428 */
4429struct file_ref
4430{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004431 int handle;
4432 int flags;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004433};
4434
4435struct pipe_ref
4436{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004437 int rd;
4438 int wr;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004439};
4440
4441/* The following code is derived from the win32 code */
4442
4443static PyObject *
4444_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4445{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004446 struct file_ref stdio[3];
4447 struct pipe_ref p_fd[3];
4448 FILE *p_s[3];
4449 int file_count, i, pipe_err;
4450 pid_t pipe_pid;
4451 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4452 PyObject *f, *p_f[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004453
Victor Stinnerd6f85422010-05-05 23:33:33 +00004454 /* file modes for subsequent fdopen's on pipe handles */
4455 if (mode == O_TEXT)
4456 {
4457 rd_mode = "rt";
4458 wr_mode = "wt";
4459 }
4460 else
4461 {
4462 rd_mode = "rb";
4463 wr_mode = "wb";
4464 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004465
Victor Stinnerd6f85422010-05-05 23:33:33 +00004466 /* prepare shell references */
4467 if ((shell = getenv("EMXSHELL")) == NULL)
4468 if ((shell = getenv("COMSPEC")) == NULL)
4469 {
4470 errno = ENOENT;
4471 return posix_error();
4472 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004473
Victor Stinnerd6f85422010-05-05 23:33:33 +00004474 sh_name = _getname(shell);
4475 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4476 opt = "/c";
4477 else
4478 opt = "-c";
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004479
Victor Stinnerd6f85422010-05-05 23:33:33 +00004480 /* save current stdio fds + their flags, and set not inheritable */
4481 i = pipe_err = 0;
4482 while (pipe_err >= 0 && i < 3)
4483 {
4484 pipe_err = stdio[i].handle = dup(i);
4485 stdio[i].flags = fcntl(i, F_GETFD, 0);
4486 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4487 i++;
4488 }
4489 if (pipe_err < 0)
4490 {
4491 /* didn't get them all saved - clean up and bail out */
4492 int saved_err = errno;
4493 while (i-- > 0)
4494 {
4495 close(stdio[i].handle);
4496 }
4497 errno = saved_err;
4498 return posix_error();
4499 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004500
Victor Stinnerd6f85422010-05-05 23:33:33 +00004501 /* create pipe ends */
4502 file_count = 2;
4503 if (n == POPEN_3)
4504 file_count = 3;
4505 i = pipe_err = 0;
4506 while ((pipe_err == 0) && (i < file_count))
4507 pipe_err = pipe((int *)&p_fd[i++]);
4508 if (pipe_err < 0)
4509 {
4510 /* didn't get them all made - clean up and bail out */
4511 while (i-- > 0)
4512 {
4513 close(p_fd[i].wr);
4514 close(p_fd[i].rd);
4515 }
4516 errno = EPIPE;
4517 return posix_error();
4518 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004519
Victor Stinnerd6f85422010-05-05 23:33:33 +00004520 /* change the actual standard IO streams over temporarily,
4521 * making the retained pipe ends non-inheritable
4522 */
4523 pipe_err = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004524
Victor Stinnerd6f85422010-05-05 23:33:33 +00004525 /* - stdin */
4526 if (dup2(p_fd[0].rd, 0) == 0)
4527 {
4528 close(p_fd[0].rd);
4529 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4530 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4531 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4532 {
4533 close(p_fd[0].wr);
4534 pipe_err = -1;
4535 }
4536 }
4537 else
4538 {
4539 pipe_err = -1;
4540 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004541
Victor Stinnerd6f85422010-05-05 23:33:33 +00004542 /* - stdout */
4543 if (pipe_err == 0)
4544 {
4545 if (dup2(p_fd[1].wr, 1) == 1)
4546 {
4547 close(p_fd[1].wr);
4548 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4549 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4550 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4551 {
4552 close(p_fd[1].rd);
4553 pipe_err = -1;
4554 }
4555 }
4556 else
4557 {
4558 pipe_err = -1;
4559 }
4560 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004561
Victor Stinnerd6f85422010-05-05 23:33:33 +00004562 /* - stderr, as required */
4563 if (pipe_err == 0)
4564 switch (n)
4565 {
4566 case POPEN_3:
4567 {
4568 if (dup2(p_fd[2].wr, 2) == 2)
4569 {
4570 close(p_fd[2].wr);
4571 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4572 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4573 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4574 {
4575 close(p_fd[2].rd);
4576 pipe_err = -1;
4577 }
4578 }
4579 else
4580 {
4581 pipe_err = -1;
4582 }
4583 break;
4584 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004585
Victor Stinnerd6f85422010-05-05 23:33:33 +00004586 case POPEN_4:
4587 {
4588 if (dup2(1, 2) != 2)
4589 {
4590 pipe_err = -1;
4591 }
4592 break;
4593 }
4594 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004595
Victor Stinnerd6f85422010-05-05 23:33:33 +00004596 /* spawn the child process */
4597 if (pipe_err == 0)
4598 {
4599 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4600 if (pipe_pid == -1)
4601 {
4602 pipe_err = -1;
4603 }
4604 else
4605 {
4606 /* save the PID into the FILE structure
4607 * NOTE: this implementation doesn't actually
4608 * take advantage of this, but do it for
4609 * completeness - AIM Apr01
4610 */
4611 for (i = 0; i < file_count; i++)
4612 p_s[i]->_pid = pipe_pid;
4613 }
4614 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004615
Victor Stinnerd6f85422010-05-05 23:33:33 +00004616 /* reset standard IO to normal */
4617 for (i = 0; i < 3; i++)
4618 {
4619 dup2(stdio[i].handle, i);
4620 fcntl(i, F_SETFD, stdio[i].flags);
4621 close(stdio[i].handle);
4622 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004623
Victor Stinnerd6f85422010-05-05 23:33:33 +00004624 /* if any remnant problems, clean up and bail out */
4625 if (pipe_err < 0)
4626 {
4627 for (i = 0; i < 3; i++)
4628 {
4629 close(p_fd[i].rd);
4630 close(p_fd[i].wr);
4631 }
4632 errno = EPIPE;
4633 return posix_error_with_filename(cmdstring);
4634 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004635
Victor Stinnerd6f85422010-05-05 23:33:33 +00004636 /* build tuple of file objects to return */
4637 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4638 PyFile_SetBufSize(p_f[0], bufsize);
4639 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4640 PyFile_SetBufSize(p_f[1], bufsize);
4641 if (n == POPEN_3)
4642 {
4643 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4644 PyFile_SetBufSize(p_f[0], bufsize);
4645 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4646 }
4647 else
4648 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004649
Victor Stinnerd6f85422010-05-05 23:33:33 +00004650 /*
4651 * Insert the files we've created into the process dictionary
4652 * all referencing the list with the process handle and the
4653 * initial number of files (see description below in _PyPclose).
4654 * Since if _PyPclose later tried to wait on a process when all
4655 * handles weren't closed, it could create a deadlock with the
4656 * child, we spend some energy here to try to ensure that we
4657 * either insert all file handles into the dictionary or none
4658 * at all. It's a little clumsy with the various popen modes
4659 * and variable number of files involved.
4660 */
4661 if (!_PyPopenProcs)
4662 {
4663 _PyPopenProcs = PyDict_New();
4664 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004665
Victor Stinnerd6f85422010-05-05 23:33:33 +00004666 if (_PyPopenProcs)
4667 {
4668 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4669 int ins_rc[3];
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004670
Victor Stinnerd6f85422010-05-05 23:33:33 +00004671 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4672 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004673
Victor Stinnerd6f85422010-05-05 23:33:33 +00004674 procObj = PyList_New(2);
4675 pidObj = PyLong_FromPid(pipe_pid);
4676 intObj = PyInt_FromLong((long) file_count);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004677
Victor Stinnerd6f85422010-05-05 23:33:33 +00004678 if (procObj && pidObj && intObj)
4679 {
4680 PyList_SetItem(procObj, 0, pidObj);
4681 PyList_SetItem(procObj, 1, intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004682
Victor Stinnerd6f85422010-05-05 23:33:33 +00004683 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4684 if (fileObj[0])
4685 {
4686 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4687 fileObj[0],
4688 procObj);
4689 }
4690 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4691 if (fileObj[1])
4692 {
4693 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4694 fileObj[1],
4695 procObj);
4696 }
4697 if (file_count >= 3)
4698 {
4699 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4700 if (fileObj[2])
4701 {
4702 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4703 fileObj[2],
4704 procObj);
4705 }
4706 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004707
Victor Stinnerd6f85422010-05-05 23:33:33 +00004708 if (ins_rc[0] < 0 || !fileObj[0] ||
4709 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4710 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4711 {
4712 /* Something failed - remove any dictionary
4713 * entries that did make it.
4714 */
4715 if (!ins_rc[0] && fileObj[0])
4716 {
4717 PyDict_DelItem(_PyPopenProcs,
4718 fileObj[0]);
4719 }
4720 if (!ins_rc[1] && fileObj[1])
4721 {
4722 PyDict_DelItem(_PyPopenProcs,
4723 fileObj[1]);
4724 }
4725 if (!ins_rc[2] && fileObj[2])
4726 {
4727 PyDict_DelItem(_PyPopenProcs,
4728 fileObj[2]);
4729 }
4730 }
4731 }
Tim Peters11b23062003-04-23 02:39:17 +00004732
Victor Stinnerd6f85422010-05-05 23:33:33 +00004733 /*
4734 * Clean up our localized references for the dictionary keys
4735 * and value since PyDict_SetItem will Py_INCREF any copies
4736 * that got placed in the dictionary.
4737 */
4738 Py_XDECREF(procObj);
4739 Py_XDECREF(fileObj[0]);
4740 Py_XDECREF(fileObj[1]);
4741 Py_XDECREF(fileObj[2]);
4742 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004743
Victor Stinnerd6f85422010-05-05 23:33:33 +00004744 /* Child is launched. */
4745 return f;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004746}
4747
4748/*
4749 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4750 * exit code for the child process and return as a result of the close.
4751 *
4752 * This function uses the _PyPopenProcs dictionary in order to map the
4753 * input file pointer to information about the process that was
4754 * originally created by the popen* call that created the file pointer.
4755 * The dictionary uses the file pointer as a key (with one entry
4756 * inserted for each file returned by the original popen* call) and a
4757 * single list object as the value for all files from a single call.
4758 * The list object contains the Win32 process handle at [0], and a file
4759 * count at [1], which is initialized to the total number of file
4760 * handles using that list.
4761 *
4762 * This function closes whichever handle it is passed, and decrements
4763 * the file count in the dictionary for the process handle pointed to
4764 * by this file. On the last close (when the file count reaches zero),
4765 * this function will wait for the child process and then return its
4766 * exit code as the result of the close() operation. This permits the
4767 * files to be closed in any order - it is always the close() of the
4768 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004769 *
4770 * NOTE: This function is currently called with the GIL released.
4771 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004772 */
4773
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004774static int _PyPclose(FILE *file)
4775{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004776 int result;
4777 int exit_code;
4778 pid_t pipe_pid;
4779 PyObject *procObj, *pidObj, *intObj, *fileObj;
4780 int file_count;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004781#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004782 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004783#endif
4784
Victor Stinnerd6f85422010-05-05 23:33:33 +00004785 /* Close the file handle first, to ensure it can't block the
4786 * child from exiting if it's the last handle.
4787 */
4788 result = fclose(file);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004789
4790#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004791 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004792#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004793 if (_PyPopenProcs)
4794 {
4795 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4796 (procObj = PyDict_GetItem(_PyPopenProcs,
4797 fileObj)) != NULL &&
4798 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4799 (intObj = PyList_GetItem(procObj,1)) != NULL)
4800 {
4801 pipe_pid = (pid_t) PyLong_AsPid(pidObj);
4802 file_count = (int) PyInt_AsLong(intObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004803
Victor Stinnerd6f85422010-05-05 23:33:33 +00004804 if (file_count > 1)
4805 {
4806 /* Still other files referencing process */
4807 file_count--;
4808 PyList_SetItem(procObj,1,
4809 PyInt_FromLong((long) file_count));
4810 }
4811 else
4812 {
4813 /* Last file for this process */
4814 if (result != EOF &&
4815 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4816 {
4817 /* extract exit status */
4818 if (WIFEXITED(exit_code))
4819 {
4820 result = WEXITSTATUS(exit_code);
4821 }
4822 else
4823 {
4824 errno = EPIPE;
4825 result = -1;
4826 }
4827 }
4828 else
4829 {
4830 /* Indicate failure - this will cause the file object
4831 * to raise an I/O error and translate the last
4832 * error code from errno. We do have a problem with
4833 * last errors that overlap the normal errno table,
4834 * but that's a consistent problem with the file object.
4835 */
4836 result = -1;
4837 }
4838 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004839
Victor Stinnerd6f85422010-05-05 23:33:33 +00004840 /* Remove this file pointer from dictionary */
4841 PyDict_DelItem(_PyPopenProcs, fileObj);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004842
Victor Stinnerd6f85422010-05-05 23:33:33 +00004843 if (PyDict_Size(_PyPopenProcs) == 0)
4844 {
4845 Py_DECREF(_PyPopenProcs);
4846 _PyPopenProcs = NULL;
4847 }
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004848
Victor Stinnerd6f85422010-05-05 23:33:33 +00004849 } /* if object retrieval ok */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004850
Victor Stinnerd6f85422010-05-05 23:33:33 +00004851 Py_XDECREF(fileObj);
4852 } /* if _PyPopenProcs */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004853
4854#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00004855 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004856#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00004857 return result;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004858}
4859
4860#endif /* PYCC_??? */
4861
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004862#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004863
4864/*
4865 * Portable 'popen' replacement for Win32.
4866 *
4867 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4868 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004869 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004870 */
4871
4872#include <malloc.h>
4873#include <io.h>
4874#include <fcntl.h>
4875
4876/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4877#define POPEN_1 1
4878#define POPEN_2 2
4879#define POPEN_3 3
4880#define POPEN_4 4
4881
4882static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004883static int _PyPclose(FILE *file);
4884
4885/*
4886 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004887 * for use when retrieving the process exit code. See _PyPclose() below
4888 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004889 */
4890static PyObject *_PyPopenProcs = NULL;
4891
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892
4893/* popen that works from a GUI.
4894 *
4895 * The result of this function is a pipe (file) connected to the
4896 * processes stdin or stdout, depending on the requested mode.
4897 */
4898
4899static PyObject *
4900posix_popen(PyObject *self, PyObject *args)
4901{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004902 PyObject *f;
4903 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004904
Victor Stinnerd6f85422010-05-05 23:33:33 +00004905 char *cmdstring;
4906 char *mode = "r";
4907 int bufsize = -1;
4908 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4909 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004910
Victor Stinnerd6f85422010-05-05 23:33:33 +00004911 if (*mode == 'r')
4912 tm = _O_RDONLY;
4913 else if (*mode != 'w') {
4914 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4915 return NULL;
4916 } else
4917 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004918
Victor Stinnerd6f85422010-05-05 23:33:33 +00004919 if (bufsize != -1) {
4920 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4921 return NULL;
4922 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004923
Victor Stinnerd6f85422010-05-05 23:33:33 +00004924 if (*(mode+1) == 't')
4925 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4926 else if (*(mode+1) == 'b')
4927 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4928 else
4929 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004930
Victor Stinnerd6f85422010-05-05 23:33:33 +00004931 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004932}
4933
4934/* Variation on win32pipe.popen
4935 *
4936 * The result of this function is a pipe (file) connected to the
4937 * process's stdin, and a pipe connected to the process's stdout.
4938 */
4939
4940static PyObject *
4941win32_popen2(PyObject *self, PyObject *args)
4942{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004943 PyObject *f;
4944 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004945
Victor Stinnerd6f85422010-05-05 23:33:33 +00004946 char *cmdstring;
4947 char *mode = "t";
4948 int bufsize = -1;
4949 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4950 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004951
Victor Stinnerd6f85422010-05-05 23:33:33 +00004952 if (*mode == 't')
4953 tm = _O_TEXT;
4954 else if (*mode != 'b') {
4955 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4956 return NULL;
4957 } else
4958 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004959
Victor Stinnerd6f85422010-05-05 23:33:33 +00004960 if (bufsize != -1) {
4961 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4962 return NULL;
4963 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004964
Victor Stinnerd6f85422010-05-05 23:33:33 +00004965 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004966
Victor Stinnerd6f85422010-05-05 23:33:33 +00004967 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004968}
4969
4970/*
4971 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004972 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004973 * The result of this function is 3 pipes - the process's stdin,
4974 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004975 */
4976
4977static PyObject *
4978win32_popen3(PyObject *self, PyObject *args)
4979{
Victor Stinnerd6f85422010-05-05 23:33:33 +00004980 PyObject *f;
4981 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004982
Victor Stinnerd6f85422010-05-05 23:33:33 +00004983 char *cmdstring;
4984 char *mode = "t";
4985 int bufsize = -1;
4986 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4987 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004988
Victor Stinnerd6f85422010-05-05 23:33:33 +00004989 if (*mode == 't')
4990 tm = _O_TEXT;
4991 else if (*mode != 'b') {
4992 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4993 return NULL;
4994 } else
4995 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Victor Stinnerd6f85422010-05-05 23:33:33 +00004997 if (bufsize != -1) {
4998 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4999 return NULL;
5000 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005001
Victor Stinnerd6f85422010-05-05 23:33:33 +00005002 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00005003
Victor Stinnerd6f85422010-05-05 23:33:33 +00005004 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005005}
5006
5007/*
5008 * Variation on win32pipe.popen
5009 *
Tim Peters5aa91602002-01-30 05:46:57 +00005010 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005011 * and stdout+stderr combined as a single pipe.
5012 */
5013
5014static PyObject *
5015win32_popen4(PyObject *self, PyObject *args)
5016{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005017 PyObject *f;
5018 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005019
Victor Stinnerd6f85422010-05-05 23:33:33 +00005020 char *cmdstring;
5021 char *mode = "t";
5022 int bufsize = -1;
5023 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
5024 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00005025
Victor Stinnerd6f85422010-05-05 23:33:33 +00005026 if (*mode == 't')
5027 tm = _O_TEXT;
5028 else if (*mode != 'b') {
5029 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
5030 return NULL;
5031 } else
5032 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005033
Victor Stinnerd6f85422010-05-05 23:33:33 +00005034 if (bufsize != -1) {
5035 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
5036 return NULL;
5037 }
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005038
Victor Stinnerd6f85422010-05-05 23:33:33 +00005039 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00005040
Victor Stinnerd6f85422010-05-05 23:33:33 +00005041 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005042}
5043
Mark Hammond08501372001-01-31 07:30:29 +00005044static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00005045_PyPopenCreateProcess(char *cmdstring,
Victor Stinnerd6f85422010-05-05 23:33:33 +00005046 HANDLE hStdin,
5047 HANDLE hStdout,
5048 HANDLE hStderr,
5049 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005050{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005051 PROCESS_INFORMATION piProcInfo;
5052 STARTUPINFO siStartInfo;
5053 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
5054 char *s1,*s2, *s3 = " /c ";
5055 const char *szConsoleSpawn = "w9xpopen.exe";
5056 int i;
5057 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005058
Victor Stinnerd6f85422010-05-05 23:33:33 +00005059 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
5060 char *comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005061
Victor Stinnerd6f85422010-05-05 23:33:33 +00005062 s1 = (char *)alloca(i);
5063 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
5064 /* x < i, so x fits into an integer */
5065 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00005066
Victor Stinnerd6f85422010-05-05 23:33:33 +00005067 /* Explicitly check if we are using COMMAND.COM. If we are
5068 * then use the w9xpopen hack.
5069 */
5070 comshell = s1 + x;
5071 while (comshell >= s1 && *comshell != '\\')
5072 --comshell;
5073 ++comshell;
Tim Peters402d5982001-08-27 06:37:48 +00005074
Victor Stinnerd6f85422010-05-05 23:33:33 +00005075 if (GetVersion() < 0x80000000 &&
5076 _stricmp(comshell, "command.com") != 0) {
5077 /* NT/2000 and not using command.com. */
5078 x = i + strlen(s3) + strlen(cmdstring) + 1;
5079 s2 = (char *)alloca(x);
5080 ZeroMemory(s2, x);
5081 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
5082 }
5083 else {
5084 /*
5085 * Oh gag, we're on Win9x or using COMMAND.COM. Use
5086 * the workaround listed in KB: Q150956
5087 */
5088 char modulepath[_MAX_PATH];
5089 struct stat statinfo;
5090 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
5091 for (x = i = 0; modulepath[i]; i++)
5092 if (modulepath[i] == SEP)
5093 x = i+1;
5094 modulepath[x] = '\0';
5095 /* Create the full-name to w9xpopen, so we can test it exists */
5096 strncat(modulepath,
5097 szConsoleSpawn,
5098 (sizeof(modulepath)/sizeof(modulepath[0]))
5099 -strlen(modulepath));
5100 if (stat(modulepath, &statinfo) != 0) {
5101 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
5102 /* Eeek - file-not-found - possibly an embedding
5103 situation - see if we can locate it in sys.prefix
5104 */
5105 strncpy(modulepath,
5106 Py_GetExecPrefix(),
5107 mplen);
5108 modulepath[mplen-1] = '\0';
5109 if (modulepath[strlen(modulepath)-1] != '\\')
5110 strcat(modulepath, "\\");
5111 strncat(modulepath,
5112 szConsoleSpawn,
5113 mplen-strlen(modulepath));
5114 /* No where else to look - raise an easily identifiable
5115 error, rather than leaving Windows to report
5116 "file not found" - as the user is probably blissfully
5117 unaware this shim EXE is used, and it will confuse them.
5118 (well, it confused me for a while ;-)
5119 */
5120 if (stat(modulepath, &statinfo) != 0) {
5121 PyErr_Format(PyExc_RuntimeError,
5122 "Can not locate '%s' which is needed "
5123 "for popen to work with your shell "
5124 "or platform.",
5125 szConsoleSpawn);
5126 return FALSE;
5127 }
5128 }
5129 x = i + strlen(s3) + strlen(cmdstring) + 1 +
5130 strlen(modulepath) +
5131 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00005132
Victor Stinnerd6f85422010-05-05 23:33:33 +00005133 s2 = (char *)alloca(x);
5134 ZeroMemory(s2, x);
5135 /* To maintain correct argument passing semantics,
5136 we pass the command-line as it stands, and allow
5137 quoting to be applied. w9xpopen.exe will then
5138 use its argv vector, and re-quote the necessary
5139 args for the ultimate child process.
5140 */
5141 PyOS_snprintf(
5142 s2, x,
5143 "\"%s\" %s%s%s",
5144 modulepath,
5145 s1,
5146 s3,
5147 cmdstring);
5148 /* Not passing CREATE_NEW_CONSOLE has been known to
5149 cause random failures on win9x. Specifically a
5150 dialog:
5151 "Your program accessed mem currently in use at xxx"
5152 and a hopeful warning about the stability of your
5153 system.
5154 Cost is Ctrl+C won't kill children, but anyone
5155 who cares can have a go!
5156 */
5157 dwProcessFlags |= CREATE_NEW_CONSOLE;
5158 }
5159 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005160
Victor Stinnerd6f85422010-05-05 23:33:33 +00005161 /* Could be an else here to try cmd.exe / command.com in the path
5162 Now we'll just error out.. */
5163 else {
5164 PyErr_SetString(PyExc_RuntimeError,
5165 "Cannot locate a COMSPEC environment variable to "
5166 "use as the shell");
5167 return FALSE;
5168 }
Tim Peters5aa91602002-01-30 05:46:57 +00005169
Victor Stinnerd6f85422010-05-05 23:33:33 +00005170 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5171 siStartInfo.cb = sizeof(STARTUPINFO);
5172 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5173 siStartInfo.hStdInput = hStdin;
5174 siStartInfo.hStdOutput = hStdout;
5175 siStartInfo.hStdError = hStderr;
5176 siStartInfo.wShowWindow = SW_HIDE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005177
Victor Stinnerd6f85422010-05-05 23:33:33 +00005178 if (CreateProcess(NULL,
5179 s2,
5180 NULL,
5181 NULL,
5182 TRUE,
5183 dwProcessFlags,
5184 NULL,
5185 NULL,
5186 &siStartInfo,
5187 &piProcInfo) ) {
5188 /* Close the handles now so anyone waiting is woken. */
5189 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005190
Victor Stinnerd6f85422010-05-05 23:33:33 +00005191 /* Return process handle */
5192 *hProcess = piProcInfo.hProcess;
5193 return TRUE;
5194 }
5195 win32_error("CreateProcess", s2);
5196 return FALSE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005197}
5198
5199/* The following code is based off of KB: Q190351 */
5200
5201static PyObject *
5202_PyPopen(char *cmdstring, int mode, int n)
5203{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005204 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5205 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5206 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00005207
Victor Stinnerd6f85422010-05-05 23:33:33 +00005208 SECURITY_ATTRIBUTES saAttr;
5209 BOOL fSuccess;
5210 int fd1, fd2, fd3;
5211 FILE *f1, *f2, *f3;
5212 long file_count;
5213 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005214
Victor Stinnerd6f85422010-05-05 23:33:33 +00005215 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5216 saAttr.bInheritHandle = TRUE;
5217 saAttr.lpSecurityDescriptor = NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005218
Victor Stinnerd6f85422010-05-05 23:33:33 +00005219 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5220 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005221
Victor Stinnerd6f85422010-05-05 23:33:33 +00005222 /* Create new output read handle and the input write handle. Set
5223 * the inheritance properties to FALSE. Otherwise, the child inherits
5224 * these handles; resulting in non-closeable handles to the pipes
5225 * being created. */
5226 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5227 GetCurrentProcess(), &hChildStdinWrDup, 0,
5228 FALSE,
5229 DUPLICATE_SAME_ACCESS);
5230 if (!fSuccess)
5231 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005232
Victor Stinnerd6f85422010-05-05 23:33:33 +00005233 /* Close the inheritable version of ChildStdin
5234 that we're using. */
5235 CloseHandle(hChildStdinWr);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236
Victor Stinnerd6f85422010-05-05 23:33:33 +00005237 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5238 return win32_error("CreatePipe", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005239
Victor Stinnerd6f85422010-05-05 23:33:33 +00005240 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5241 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5242 FALSE, DUPLICATE_SAME_ACCESS);
5243 if (!fSuccess)
5244 return win32_error("DuplicateHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005245
Victor Stinnerd6f85422010-05-05 23:33:33 +00005246 /* Close the inheritable version of ChildStdout
5247 that we're using. */
5248 CloseHandle(hChildStdoutRd);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005249
Victor Stinnerd6f85422010-05-05 23:33:33 +00005250 if (n != POPEN_4) {
5251 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5252 return win32_error("CreatePipe", NULL);
5253 fSuccess = DuplicateHandle(GetCurrentProcess(),
5254 hChildStderrRd,
5255 GetCurrentProcess(),
5256 &hChildStderrRdDup, 0,
5257 FALSE, DUPLICATE_SAME_ACCESS);
5258 if (!fSuccess)
5259 return win32_error("DuplicateHandle", NULL);
5260 /* Close the inheritable version of ChildStdErr that we're using. */
5261 CloseHandle(hChildStderrRd);
5262 }
Tim Peters5aa91602002-01-30 05:46:57 +00005263
Victor Stinnerd6f85422010-05-05 23:33:33 +00005264 switch (n) {
5265 case POPEN_1:
5266 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5267 case _O_WRONLY | _O_TEXT:
5268 /* Case for writing to child Stdin in text mode. */
5269 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5270 f1 = _fdopen(fd1, "w");
5271 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5272 PyFile_SetBufSize(f, 0);
5273 /* We don't care about these pipes anymore, so close them. */
5274 CloseHandle(hChildStdoutRdDup);
5275 CloseHandle(hChildStderrRdDup);
5276 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005277
Victor Stinnerd6f85422010-05-05 23:33:33 +00005278 case _O_RDONLY | _O_TEXT:
5279 /* Case for reading from child Stdout in text mode. */
5280 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5281 f1 = _fdopen(fd1, "r");
5282 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5283 PyFile_SetBufSize(f, 0);
5284 /* We don't care about these pipes anymore, so close them. */
5285 CloseHandle(hChildStdinWrDup);
5286 CloseHandle(hChildStderrRdDup);
5287 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005288
Victor Stinnerd6f85422010-05-05 23:33:33 +00005289 case _O_RDONLY | _O_BINARY:
5290 /* Case for readinig from child Stdout in binary mode. */
5291 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5292 f1 = _fdopen(fd1, "rb");
5293 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5294 PyFile_SetBufSize(f, 0);
5295 /* We don't care about these pipes anymore, so close them. */
5296 CloseHandle(hChildStdinWrDup);
5297 CloseHandle(hChildStderrRdDup);
5298 break;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005299
Victor Stinnerd6f85422010-05-05 23:33:33 +00005300 case _O_WRONLY | _O_BINARY:
5301 /* Case for writing to child Stdin in binary mode. */
5302 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5303 f1 = _fdopen(fd1, "wb");
5304 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5305 PyFile_SetBufSize(f, 0);
5306 /* We don't care about these pipes anymore, so close them. */
5307 CloseHandle(hChildStdoutRdDup);
5308 CloseHandle(hChildStderrRdDup);
5309 break;
5310 }
5311 file_count = 1;
5312 break;
Tim Peters5aa91602002-01-30 05:46:57 +00005313
Victor Stinnerd6f85422010-05-05 23:33:33 +00005314 case POPEN_2:
5315 case POPEN_4:
5316 {
5317 char *m1, *m2;
5318 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00005319
Victor Stinnerd6f85422010-05-05 23:33:33 +00005320 if (mode & _O_TEXT) {
5321 m1 = "r";
5322 m2 = "w";
5323 } else {
5324 m1 = "rb";
5325 m2 = "wb";
5326 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005327
Victor Stinnerd6f85422010-05-05 23:33:33 +00005328 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5329 f1 = _fdopen(fd1, m2);
5330 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5331 f2 = _fdopen(fd2, m1);
5332 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5333 PyFile_SetBufSize(p1, 0);
5334 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5335 PyFile_SetBufSize(p2, 0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005336
Victor Stinnerd6f85422010-05-05 23:33:33 +00005337 if (n != 4)
5338 CloseHandle(hChildStderrRdDup);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005339
Victor Stinnerd6f85422010-05-05 23:33:33 +00005340 f = PyTuple_Pack(2,p1,p2);
5341 Py_XDECREF(p1);
5342 Py_XDECREF(p2);
5343 file_count = 2;
5344 break;
5345 }
Tim Peters5aa91602002-01-30 05:46:57 +00005346
Victor Stinnerd6f85422010-05-05 23:33:33 +00005347 case POPEN_3:
5348 {
5349 char *m1, *m2;
5350 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00005351
Victor Stinnerd6f85422010-05-05 23:33:33 +00005352 if (mode & _O_TEXT) {
5353 m1 = "r";
5354 m2 = "w";
5355 } else {
5356 m1 = "rb";
5357 m2 = "wb";
5358 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005359
Victor Stinnerd6f85422010-05-05 23:33:33 +00005360 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5361 f1 = _fdopen(fd1, m2);
5362 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5363 f2 = _fdopen(fd2, m1);
5364 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5365 f3 = _fdopen(fd3, m1);
5366 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5367 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5368 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5369 PyFile_SetBufSize(p1, 0);
5370 PyFile_SetBufSize(p2, 0);
5371 PyFile_SetBufSize(p3, 0);
5372 f = PyTuple_Pack(3,p1,p2,p3);
5373 Py_XDECREF(p1);
5374 Py_XDECREF(p2);
5375 Py_XDECREF(p3);
5376 file_count = 3;
5377 break;
5378 }
5379 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005380
Victor Stinnerd6f85422010-05-05 23:33:33 +00005381 if (n == POPEN_4) {
5382 if (!_PyPopenCreateProcess(cmdstring,
5383 hChildStdinRd,
5384 hChildStdoutWr,
5385 hChildStdoutWr,
5386 &hProcess))
5387 return NULL;
5388 }
5389 else {
5390 if (!_PyPopenCreateProcess(cmdstring,
5391 hChildStdinRd,
5392 hChildStdoutWr,
5393 hChildStderrWr,
5394 &hProcess))
5395 return NULL;
5396 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005397
Victor Stinnerd6f85422010-05-05 23:33:33 +00005398 /*
5399 * Insert the files we've created into the process dictionary
5400 * all referencing the list with the process handle and the
5401 * initial number of files (see description below in _PyPclose).
5402 * Since if _PyPclose later tried to wait on a process when all
5403 * handles weren't closed, it could create a deadlock with the
5404 * child, we spend some energy here to try to ensure that we
5405 * either insert all file handles into the dictionary or none
5406 * at all. It's a little clumsy with the various popen modes
5407 * and variable number of files involved.
5408 */
5409 if (!_PyPopenProcs) {
5410 _PyPopenProcs = PyDict_New();
5411 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005412
Victor Stinnerd6f85422010-05-05 23:33:33 +00005413 if (_PyPopenProcs) {
5414 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5415 int ins_rc[3];
Mark Hammondb37a3732000-08-14 04:47:33 +00005416
Victor Stinnerd6f85422010-05-05 23:33:33 +00005417 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5418 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
Mark Hammondb37a3732000-08-14 04:47:33 +00005419
Victor Stinnerd6f85422010-05-05 23:33:33 +00005420 procObj = PyList_New(2);
5421 hProcessObj = PyLong_FromVoidPtr(hProcess);
5422 intObj = PyInt_FromLong(file_count);
Mark Hammondb37a3732000-08-14 04:47:33 +00005423
Victor Stinnerd6f85422010-05-05 23:33:33 +00005424 if (procObj && hProcessObj && intObj) {
5425 PyList_SetItem(procObj,0,hProcessObj);
5426 PyList_SetItem(procObj,1,intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005427
Victor Stinnerd6f85422010-05-05 23:33:33 +00005428 fileObj[0] = PyLong_FromVoidPtr(f1);
5429 if (fileObj[0]) {
5430 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5431 fileObj[0],
5432 procObj);
5433 }
5434 if (file_count >= 2) {
5435 fileObj[1] = PyLong_FromVoidPtr(f2);
5436 if (fileObj[1]) {
5437 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5438 fileObj[1],
5439 procObj);
5440 }
5441 }
5442 if (file_count >= 3) {
5443 fileObj[2] = PyLong_FromVoidPtr(f3);
5444 if (fileObj[2]) {
5445 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5446 fileObj[2],
5447 procObj);
5448 }
5449 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005450
Victor Stinnerd6f85422010-05-05 23:33:33 +00005451 if (ins_rc[0] < 0 || !fileObj[0] ||
5452 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5453 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5454 /* Something failed - remove any dictionary
5455 * entries that did make it.
5456 */
5457 if (!ins_rc[0] && fileObj[0]) {
5458 PyDict_DelItem(_PyPopenProcs,
5459 fileObj[0]);
5460 }
5461 if (!ins_rc[1] && fileObj[1]) {
5462 PyDict_DelItem(_PyPopenProcs,
5463 fileObj[1]);
5464 }
5465 if (!ins_rc[2] && fileObj[2]) {
5466 PyDict_DelItem(_PyPopenProcs,
5467 fileObj[2]);
5468 }
5469 }
5470 }
Tim Peters5aa91602002-01-30 05:46:57 +00005471
Victor Stinnerd6f85422010-05-05 23:33:33 +00005472 /*
5473 * Clean up our localized references for the dictionary keys
5474 * and value since PyDict_SetItem will Py_INCREF any copies
5475 * that got placed in the dictionary.
5476 */
5477 Py_XDECREF(procObj);
5478 Py_XDECREF(fileObj[0]);
5479 Py_XDECREF(fileObj[1]);
5480 Py_XDECREF(fileObj[2]);
5481 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005482
Victor Stinnerd6f85422010-05-05 23:33:33 +00005483 /* Child is launched. Close the parents copy of those pipe
5484 * handles that only the child should have open. You need to
5485 * make sure that no handles to the write end of the output pipe
5486 * are maintained in this process or else the pipe will not close
5487 * when the child process exits and the ReadFile will hang. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005488
Victor Stinnerd6f85422010-05-05 23:33:33 +00005489 if (!CloseHandle(hChildStdinRd))
5490 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005491
Victor Stinnerd6f85422010-05-05 23:33:33 +00005492 if (!CloseHandle(hChildStdoutWr))
5493 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005494
Victor Stinnerd6f85422010-05-05 23:33:33 +00005495 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5496 return win32_error("CloseHandle", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005497
Victor Stinnerd6f85422010-05-05 23:33:33 +00005498 return f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005499}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005500
5501/*
5502 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5503 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005504 *
5505 * This function uses the _PyPopenProcs dictionary in order to map the
5506 * input file pointer to information about the process that was
5507 * originally created by the popen* call that created the file pointer.
5508 * The dictionary uses the file pointer as a key (with one entry
5509 * inserted for each file returned by the original popen* call) and a
5510 * single list object as the value for all files from a single call.
5511 * The list object contains the Win32 process handle at [0], and a file
5512 * count at [1], which is initialized to the total number of file
5513 * handles using that list.
5514 *
5515 * This function closes whichever handle it is passed, and decrements
5516 * the file count in the dictionary for the process handle pointed to
5517 * by this file. On the last close (when the file count reaches zero),
5518 * this function will wait for the child process and then return its
5519 * exit code as the result of the close() operation. This permits the
5520 * files to be closed in any order - it is always the close() of the
5521 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005522 *
5523 * NOTE: This function is currently called with the GIL released.
5524 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005525 */
Tim Peters736aa322000-09-01 06:51:24 +00005526
Fredrik Lundh56055a42000-07-23 19:47:12 +00005527static int _PyPclose(FILE *file)
5528{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005529 int result;
5530 DWORD exit_code;
5531 HANDLE hProcess;
5532 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5533 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005534#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005535 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005536#endif
5537
Victor Stinnerd6f85422010-05-05 23:33:33 +00005538 /* Close the file handle first, to ensure it can't block the
5539 * child from exiting if it's the last handle.
5540 */
5541 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005542#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005543 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005544#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005545 if (_PyPopenProcs) {
5546 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5547 (procObj = PyDict_GetItem(_PyPopenProcs,
5548 fileObj)) != NULL &&
5549 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5550 (intObj = PyList_GetItem(procObj,1)) != NULL) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005551
Victor Stinnerd6f85422010-05-05 23:33:33 +00005552 hProcess = PyLong_AsVoidPtr(hProcessObj);
5553 file_count = PyInt_AsLong(intObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005554
Victor Stinnerd6f85422010-05-05 23:33:33 +00005555 if (file_count > 1) {
5556 /* Still other files referencing process */
5557 file_count--;
5558 PyList_SetItem(procObj,1,
5559 PyInt_FromLong(file_count));
5560 } else {
5561 /* Last file for this process */
5562 if (result != EOF &&
5563 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5564 GetExitCodeProcess(hProcess, &exit_code)) {
5565 /* Possible truncation here in 16-bit environments, but
5566 * real exit codes are just the lower byte in any event.
5567 */
5568 result = exit_code;
5569 } else {
5570 /* Indicate failure - this will cause the file object
5571 * to raise an I/O error and translate the last Win32
5572 * error code from errno. We do have a problem with
5573 * last errors that overlap the normal errno table,
5574 * but that's a consistent problem with the file object.
5575 */
5576 if (result != EOF) {
5577 /* If the error wasn't from the fclose(), then
5578 * set errno for the file object error handling.
5579 */
5580 errno = GetLastError();
5581 }
5582 result = -1;
5583 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005584
Victor Stinnerd6f85422010-05-05 23:33:33 +00005585 /* Free up the native handle at this point */
5586 CloseHandle(hProcess);
5587 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005588
Victor Stinnerd6f85422010-05-05 23:33:33 +00005589 /* Remove this file pointer from dictionary */
5590 PyDict_DelItem(_PyPopenProcs, fileObj);
Mark Hammondb37a3732000-08-14 04:47:33 +00005591
Victor Stinnerd6f85422010-05-05 23:33:33 +00005592 if (PyDict_Size(_PyPopenProcs) == 0) {
5593 Py_DECREF(_PyPopenProcs);
5594 _PyPopenProcs = NULL;
5595 }
Mark Hammondb37a3732000-08-14 04:47:33 +00005596
Victor Stinnerd6f85422010-05-05 23:33:33 +00005597 } /* if object retrieval ok */
Mark Hammondb37a3732000-08-14 04:47:33 +00005598
Victor Stinnerd6f85422010-05-05 23:33:33 +00005599 Py_XDECREF(fileObj);
5600 } /* if _PyPopenProcs */
Fredrik Lundh56055a42000-07-23 19:47:12 +00005601
Tim Peters736aa322000-09-01 06:51:24 +00005602#ifdef WITH_THREAD
Victor Stinnerd6f85422010-05-05 23:33:33 +00005603 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005604#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00005605 return result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005606}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005607
5608#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005610posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005611{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005612 char *name;
5613 char *mode = "r";
5614 int bufsize = -1;
5615 FILE *fp;
5616 PyObject *f;
5617 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5618 return NULL;
5619 /* Strip mode of binary or text modifiers */
5620 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5621 mode = "r";
5622 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5623 mode = "w";
5624 Py_BEGIN_ALLOW_THREADS
5625 fp = popen(name, mode);
5626 Py_END_ALLOW_THREADS
5627 if (fp == NULL)
5628 return posix_error();
5629 f = PyFile_FromFile(fp, name, mode, pclose);
5630 if (f != NULL)
5631 PyFile_SetBufSize(f, bufsize);
5632 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005633}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005634
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005635#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005636#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005638
Guido van Rossumb6775db1994-08-01 11:34:53 +00005639#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005640PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005641"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005642Set the current process's user id.");
5643
Barry Warsaw53699e91996-12-10 23:23:01 +00005644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005645posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005646{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005647 long uid_arg;
5648 uid_t uid;
5649 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
5650 return NULL;
5651 uid = uid_arg;
5652 if (uid != uid_arg) {
5653 PyErr_SetString(PyExc_OverflowError, "user id too big");
5654 return NULL;
5655 }
5656 if (setuid(uid) < 0)
5657 return posix_error();
5658 Py_INCREF(Py_None);
5659 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005660}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005661#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005663
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005664#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005665PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005666"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667Set the current process's effective user id.");
5668
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005669static PyObject *
5670posix_seteuid (PyObject *self, PyObject *args)
5671{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005672 long euid_arg;
5673 uid_t euid;
5674 if (!PyArg_ParseTuple(args, "l", &euid_arg))
5675 return NULL;
5676 euid = euid_arg;
5677 if (euid != euid_arg) {
5678 PyErr_SetString(PyExc_OverflowError, "user id too big");
5679 return NULL;
5680 }
5681 if (seteuid(euid) < 0) {
5682 return posix_error();
5683 } else {
5684 Py_INCREF(Py_None);
5685 return Py_None;
5686 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005687}
5688#endif /* HAVE_SETEUID */
5689
5690#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005692"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005693Set the current process's effective group id.");
5694
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005695static PyObject *
5696posix_setegid (PyObject *self, PyObject *args)
5697{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005698 long egid_arg;
5699 gid_t egid;
5700 if (!PyArg_ParseTuple(args, "l", &egid_arg))
5701 return NULL;
5702 egid = egid_arg;
5703 if (egid != egid_arg) {
5704 PyErr_SetString(PyExc_OverflowError, "group id too big");
5705 return NULL;
5706 }
5707 if (setegid(egid) < 0) {
5708 return posix_error();
5709 } else {
5710 Py_INCREF(Py_None);
5711 return Py_None;
5712 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005713}
5714#endif /* HAVE_SETEGID */
5715
5716#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005717PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005718"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005719Set the current process's real and effective user ids.");
5720
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005721static PyObject *
5722posix_setreuid (PyObject *self, PyObject *args)
5723{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005724 long ruid_arg, euid_arg;
5725 uid_t ruid, euid;
5726 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
5727 return NULL;
5728 if (ruid_arg == -1)
5729 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
5730 else
5731 ruid = ruid_arg; /* otherwise, assign from our long */
5732 if (euid_arg == -1)
5733 euid = (uid_t)-1;
5734 else
5735 euid = euid_arg;
5736 if ((euid_arg != -1 && euid != euid_arg) ||
5737 (ruid_arg != -1 && ruid != ruid_arg)) {
5738 PyErr_SetString(PyExc_OverflowError, "user id too big");
5739 return NULL;
5740 }
5741 if (setreuid(ruid, euid) < 0) {
5742 return posix_error();
5743 } else {
5744 Py_INCREF(Py_None);
5745 return Py_None;
5746 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005747}
5748#endif /* HAVE_SETREUID */
5749
5750#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005752"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Set the current process's real and effective group ids.");
5754
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005755static PyObject *
5756posix_setregid (PyObject *self, PyObject *args)
5757{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005758 long rgid_arg, egid_arg;
5759 gid_t rgid, egid;
5760 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
5761 return NULL;
5762 if (rgid_arg == -1)
5763 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
5764 else
5765 rgid = rgid_arg; /* otherwise, assign from our long */
5766 if (egid_arg == -1)
5767 egid = (gid_t)-1;
5768 else
5769 egid = egid_arg;
5770 if ((egid_arg != -1 && egid != egid_arg) ||
5771 (rgid_arg != -1 && rgid != rgid_arg)) {
5772 PyErr_SetString(PyExc_OverflowError, "group id too big");
5773 return NULL;
5774 }
5775 if (setregid(rgid, egid) < 0) {
5776 return posix_error();
5777 } else {
5778 Py_INCREF(Py_None);
5779 return Py_None;
5780 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005781}
5782#endif /* HAVE_SETREGID */
5783
Guido van Rossumb6775db1994-08-01 11:34:53 +00005784#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005785PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005786"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005788
Barry Warsaw53699e91996-12-10 23:23:01 +00005789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005790posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005791{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005792 long gid_arg;
5793 gid_t gid;
5794 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
5795 return NULL;
5796 gid = gid_arg;
5797 if (gid != gid_arg) {
5798 PyErr_SetString(PyExc_OverflowError, "group id too big");
5799 return NULL;
5800 }
5801 if (setgid(gid) < 0)
5802 return posix_error();
5803 Py_INCREF(Py_None);
5804 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005805}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005806#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005807
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005808#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005809PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005810"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005811Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005812
5813static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005814posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005815{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005816 int i, len;
5817 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005818
Victor Stinnerd6f85422010-05-05 23:33:33 +00005819 if (!PySequence_Check(groups)) {
5820 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5821 return NULL;
5822 }
5823 len = PySequence_Size(groups);
5824 if (len > MAX_GROUPS) {
5825 PyErr_SetString(PyExc_ValueError, "too many groups");
5826 return NULL;
5827 }
5828 for(i = 0; i < len; i++) {
5829 PyObject *elem;
5830 elem = PySequence_GetItem(groups, i);
5831 if (!elem)
5832 return NULL;
5833 if (!PyInt_Check(elem)) {
5834 if (!PyLong_Check(elem)) {
5835 PyErr_SetString(PyExc_TypeError,
5836 "groups must be integers");
5837 Py_DECREF(elem);
5838 return NULL;
5839 } else {
5840 unsigned long x = PyLong_AsUnsignedLong(elem);
5841 if (PyErr_Occurred()) {
5842 PyErr_SetString(PyExc_TypeError,
5843 "group id too big");
5844 Py_DECREF(elem);
5845 return NULL;
5846 }
5847 grouplist[i] = x;
5848 /* read back to see if it fits in gid_t */
5849 if (grouplist[i] != x) {
5850 PyErr_SetString(PyExc_TypeError,
5851 "group id too big");
5852 Py_DECREF(elem);
5853 return NULL;
5854 }
5855 }
5856 } else {
5857 long x = PyInt_AsLong(elem);
5858 grouplist[i] = x;
5859 if (grouplist[i] != x) {
5860 PyErr_SetString(PyExc_TypeError,
5861 "group id too big");
5862 Py_DECREF(elem);
5863 return NULL;
5864 }
5865 }
5866 Py_DECREF(elem);
5867 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005868
Victor Stinnerd6f85422010-05-05 23:33:33 +00005869 if (setgroups(len, grouplist) < 0)
5870 return posix_error();
5871 Py_INCREF(Py_None);
5872 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005873}
5874#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005875
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005876#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005877static PyObject *
Christian Heimesd491d712008-02-01 18:49:26 +00005878wait_helper(pid_t pid, int status, struct rusage *ru)
Neal Norwitz05a45592006-03-20 06:30:08 +00005879{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005880 PyObject *result;
5881 static PyObject *struct_rusage;
Neal Norwitz05a45592006-03-20 06:30:08 +00005882
Victor Stinnerd6f85422010-05-05 23:33:33 +00005883 if (pid == -1)
5884 return posix_error();
Neal Norwitz05a45592006-03-20 06:30:08 +00005885
Victor Stinnerd6f85422010-05-05 23:33:33 +00005886 if (struct_rusage == NULL) {
5887 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5888 if (m == NULL)
5889 return NULL;
5890 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5891 Py_DECREF(m);
5892 if (struct_rusage == NULL)
5893 return NULL;
5894 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005895
Victor Stinnerd6f85422010-05-05 23:33:33 +00005896 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5897 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5898 if (!result)
5899 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005900
5901#ifndef doubletime
5902#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5903#endif
5904
Victor Stinnerd6f85422010-05-05 23:33:33 +00005905 PyStructSequence_SET_ITEM(result, 0,
5906 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5907 PyStructSequence_SET_ITEM(result, 1,
5908 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Neal Norwitz05a45592006-03-20 06:30:08 +00005909#define SET_INT(result, index, value)\
Victor Stinnerd6f85422010-05-05 23:33:33 +00005910 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5911 SET_INT(result, 2, ru->ru_maxrss);
5912 SET_INT(result, 3, ru->ru_ixrss);
5913 SET_INT(result, 4, ru->ru_idrss);
5914 SET_INT(result, 5, ru->ru_isrss);
5915 SET_INT(result, 6, ru->ru_minflt);
5916 SET_INT(result, 7, ru->ru_majflt);
5917 SET_INT(result, 8, ru->ru_nswap);
5918 SET_INT(result, 9, ru->ru_inblock);
5919 SET_INT(result, 10, ru->ru_oublock);
5920 SET_INT(result, 11, ru->ru_msgsnd);
5921 SET_INT(result, 12, ru->ru_msgrcv);
5922 SET_INT(result, 13, ru->ru_nsignals);
5923 SET_INT(result, 14, ru->ru_nvcsw);
5924 SET_INT(result, 15, ru->ru_nivcsw);
Neal Norwitz05a45592006-03-20 06:30:08 +00005925#undef SET_INT
5926
Victor Stinnerd6f85422010-05-05 23:33:33 +00005927 if (PyErr_Occurred()) {
5928 Py_DECREF(result);
5929 return NULL;
5930 }
Neal Norwitz05a45592006-03-20 06:30:08 +00005931
Victor Stinnerd6f85422010-05-05 23:33:33 +00005932 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005933}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005934#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005935
5936#ifdef HAVE_WAIT3
5937PyDoc_STRVAR(posix_wait3__doc__,
5938"wait3(options) -> (pid, status, rusage)\n\n\
5939Wait for completion of a child process.");
5940
5941static PyObject *
5942posix_wait3(PyObject *self, PyObject *args)
5943{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005944 pid_t pid;
5945 int options;
5946 struct rusage ru;
5947 WAIT_TYPE status;
5948 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005949
Victor Stinnerd6f85422010-05-05 23:33:33 +00005950 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5951 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005952
Victor Stinnerd6f85422010-05-05 23:33:33 +00005953 Py_BEGIN_ALLOW_THREADS
5954 pid = wait3(&status, options, &ru);
5955 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00005956
Victor Stinnerd6f85422010-05-05 23:33:33 +00005957 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005958}
5959#endif /* HAVE_WAIT3 */
5960
5961#ifdef HAVE_WAIT4
5962PyDoc_STRVAR(posix_wait4__doc__,
5963"wait4(pid, options) -> (pid, status, rusage)\n\n\
5964Wait for completion of a given child process.");
5965
5966static PyObject *
5967posix_wait4(PyObject *self, PyObject *args)
5968{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005969 pid_t pid;
5970 int options;
5971 struct rusage ru;
5972 WAIT_TYPE status;
5973 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005974
Victor Stinnerd6f85422010-05-05 23:33:33 +00005975 if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
5976 return NULL;
Neal Norwitz05a45592006-03-20 06:30:08 +00005977
Victor Stinnerd6f85422010-05-05 23:33:33 +00005978 Py_BEGIN_ALLOW_THREADS
5979 pid = wait4(pid, &status, options, &ru);
5980 Py_END_ALLOW_THREADS
Neal Norwitz05a45592006-03-20 06:30:08 +00005981
Victor Stinnerd6f85422010-05-05 23:33:33 +00005982 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005983}
5984#endif /* HAVE_WAIT4 */
5985
Guido van Rossumb6775db1994-08-01 11:34:53 +00005986#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005987PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005988"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005989Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005990
Barry Warsaw53699e91996-12-10 23:23:01 +00005991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005992posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005993{
Victor Stinnerd6f85422010-05-05 23:33:33 +00005994 pid_t pid;
5995 int options;
5996 WAIT_TYPE status;
5997 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005998
Victor Stinnerd6f85422010-05-05 23:33:33 +00005999 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6000 return NULL;
6001 Py_BEGIN_ALLOW_THREADS
6002 pid = waitpid(pid, &status, options);
6003 Py_END_ALLOW_THREADS
6004 if (pid == -1)
6005 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006006
Victor Stinnerd6f85422010-05-05 23:33:33 +00006007 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006008}
6009
Tim Petersab034fa2002-02-01 11:27:43 +00006010#elif defined(HAVE_CWAIT)
6011
6012/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006013PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006014"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006015"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00006016
6017static PyObject *
6018posix_waitpid(PyObject *self, PyObject *args)
6019{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006020 Py_intptr_t pid;
6021 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00006022
Victor Stinnerd6f85422010-05-05 23:33:33 +00006023 if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
6024 return NULL;
6025 Py_BEGIN_ALLOW_THREADS
6026 pid = _cwait(&status, pid, options);
6027 Py_END_ALLOW_THREADS
6028 if (pid == -1)
6029 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006030
Victor Stinnerd6f85422010-05-05 23:33:33 +00006031 /* shift the status left a byte so this is more like the POSIX waitpid */
6032 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006033}
6034#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006035
Guido van Rossumad0ee831995-03-01 10:34:45 +00006036#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006037PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006038"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006039Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006040
Barry Warsaw53699e91996-12-10 23:23:01 +00006041static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006042posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00006043{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006044 pid_t pid;
6045 WAIT_TYPE status;
6046 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006047
Victor Stinnerd6f85422010-05-05 23:33:33 +00006048 Py_BEGIN_ALLOW_THREADS
6049 pid = wait(&status);
6050 Py_END_ALLOW_THREADS
6051 if (pid == -1)
6052 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00006053
Victor Stinnerd6f85422010-05-05 23:33:33 +00006054 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006055}
Guido van Rossumad0ee831995-03-01 10:34:45 +00006056#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00006057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006059PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006060"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006062
Barry Warsaw53699e91996-12-10 23:23:01 +00006063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006064posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006065{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006066#ifdef HAVE_LSTAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00006067 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006068#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006069#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006070 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006071#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006072 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006073#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006074#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006075}
6076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006077
Guido van Rossumb6775db1994-08-01 11:34:53 +00006078#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006082
Barry Warsaw53699e91996-12-10 23:23:01 +00006083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006085{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006086 PyObject* v;
6087 char buf[MAXPATHLEN];
6088 char *path;
6089 int n;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006090#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006091 int arg_is_unicode = 0;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006092#endif
6093
Victor Stinnerd6f85422010-05-05 23:33:33 +00006094 if (!PyArg_ParseTuple(args, "et:readlink",
6095 Py_FileSystemDefaultEncoding, &path))
6096 return NULL;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006097#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006098 v = PySequence_GetItem(args, 0);
6099 if (v == NULL) {
6100 PyMem_Free(path);
6101 return NULL;
6102 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006103
Victor Stinnerd6f85422010-05-05 23:33:33 +00006104 if (PyUnicode_Check(v)) {
6105 arg_is_unicode = 1;
6106 }
6107 Py_DECREF(v);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006108#endif
6109
Victor Stinnerd6f85422010-05-05 23:33:33 +00006110 Py_BEGIN_ALLOW_THREADS
6111 n = readlink(path, buf, (int) sizeof buf);
6112 Py_END_ALLOW_THREADS
6113 if (n < 0)
6114 return posix_error_with_allocated_filename(path);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006115
Victor Stinnerd6f85422010-05-05 23:33:33 +00006116 PyMem_Free(path);
6117 v = PyString_FromStringAndSize(buf, n);
Ronald Oussoren10168f22006-10-22 10:45:18 +00006118#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00006119 if (arg_is_unicode) {
6120 PyObject *w;
Ronald Oussoren10168f22006-10-22 10:45:18 +00006121
Victor Stinnerd6f85422010-05-05 23:33:33 +00006122 w = PyUnicode_FromEncodedObject(v,
6123 Py_FileSystemDefaultEncoding,
6124 "strict");
6125 if (w != NULL) {
6126 Py_DECREF(v);
6127 v = w;
6128 }
6129 else {
6130 /* fall back to the original byte string, as
6131 discussed in patch #683592 */
6132 PyErr_Clear();
6133 }
6134 }
Ronald Oussoren10168f22006-10-22 10:45:18 +00006135#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006136 return v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006137}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006138#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006139
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006140
Guido van Rossumb6775db1994-08-01 11:34:53 +00006141#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006143"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00006144Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006145
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006147posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006148{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006149 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006150}
6151#endif /* HAVE_SYMLINK */
6152
6153
6154#ifdef HAVE_TIMES
Guido van Rossumd48f2521997-12-05 22:19:34 +00006155#if defined(PYCC_VACPP) && defined(PYOS_OS2)
6156static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006157system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006158{
6159 ULONG value = 0;
6160
6161 Py_BEGIN_ALLOW_THREADS
6162 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
6163 Py_END_ALLOW_THREADS
6164
6165 return value;
6166}
6167
6168static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006169posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006170{
Guido van Rossumd48f2521997-12-05 22:19:34 +00006171 /* Currently Only Uptime is Provided -- Others Later */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006172 return Py_BuildValue("ddddd",
6173 (double)0 /* t.tms_utime / HZ */,
6174 (double)0 /* t.tms_stime / HZ */,
6175 (double)0 /* t.tms_cutime / HZ */,
6176 (double)0 /* t.tms_cstime / HZ */,
6177 (double)system_uptime() / 1000);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006178}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006179#else /* not OS2 */
Martin v. Löwis03824e42008-12-29 18:17:34 +00006180#define NEED_TICKS_PER_SECOND
6181static long ticks_per_second = -1;
Barry Warsaw53699e91996-12-10 23:23:01 +00006182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006183posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00006184{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006185 struct tms t;
6186 clock_t c;
6187 errno = 0;
6188 c = times(&t);
6189 if (c == (clock_t) -1)
6190 return posix_error();
6191 return Py_BuildValue("ddddd",
6192 (double)t.tms_utime / ticks_per_second,
6193 (double)t.tms_stime / ticks_per_second,
6194 (double)t.tms_cutime / ticks_per_second,
6195 (double)t.tms_cstime / ticks_per_second,
6196 (double)c / ticks_per_second);
Guido van Rossum22db57e1992-04-05 14:25:30 +00006197}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006198#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006199#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006200
6201
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006202#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006203#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00006204static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006205posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006206{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006207 FILETIME create, exit, kernel, user;
6208 HANDLE hProc;
6209 hProc = GetCurrentProcess();
6210 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6211 /* The fields of a FILETIME structure are the hi and lo part
6212 of a 64-bit value expressed in 100 nanosecond units.
6213 1e7 is one second in such units; 1e-7 the inverse.
6214 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6215 */
6216 return Py_BuildValue(
6217 "ddddd",
6218 (double)(user.dwHighDateTime*429.4967296 +
6219 user.dwLowDateTime*1e-7),
6220 (double)(kernel.dwHighDateTime*429.4967296 +
6221 kernel.dwLowDateTime*1e-7),
6222 (double)0,
6223 (double)0,
6224 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00006225}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006226#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006227
6228#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006229PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006230"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00006232#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006233
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006234
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006235#ifdef HAVE_GETSID
6236PyDoc_STRVAR(posix_getsid__doc__,
6237"getsid(pid) -> sid\n\n\
6238Call the system call getsid().");
6239
6240static PyObject *
6241posix_getsid(PyObject *self, PyObject *args)
6242{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006243 pid_t pid;
6244 int sid;
6245 if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
6246 return NULL;
6247 sid = getsid(pid);
6248 if (sid < 0)
6249 return posix_error();
6250 return PyInt_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00006251}
6252#endif /* HAVE_GETSID */
6253
6254
Guido van Rossumb6775db1994-08-01 11:34:53 +00006255#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006256PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006257"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006258Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006259
Barry Warsaw53699e91996-12-10 23:23:01 +00006260static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006261posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006262{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006263 if (setsid() < 0)
6264 return posix_error();
6265 Py_INCREF(Py_None);
6266 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006267}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006268#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006269
Guido van Rossumb6775db1994-08-01 11:34:53 +00006270#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006272"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006273Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006274
Barry Warsaw53699e91996-12-10 23:23:01 +00006275static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006276posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00006277{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006278 pid_t pid;
6279 int pgrp;
6280 if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
6281 return NULL;
6282 if (setpgid(pid, pgrp) < 0)
6283 return posix_error();
6284 Py_INCREF(Py_None);
6285 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006286}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006287#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00006288
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006289
Guido van Rossumb6775db1994-08-01 11:34:53 +00006290#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006291PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006292"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006293Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006294
Barry Warsaw53699e91996-12-10 23:23:01 +00006295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006296posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006297{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006298 int fd;
6299 pid_t pgid;
6300 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6301 return NULL;
6302 pgid = tcgetpgrp(fd);
6303 if (pgid < 0)
6304 return posix_error();
6305 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00006306}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006307#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00006308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006309
Guido van Rossumb6775db1994-08-01 11:34:53 +00006310#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006311PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006312"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006313Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006314
Barry Warsaw53699e91996-12-10 23:23:01 +00006315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006316posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00006317{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006318 int fd;
6319 pid_t pgid;
6320 if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
6321 return NULL;
6322 if (tcsetpgrp(fd, pgid) < 0)
6323 return posix_error();
6324 Py_INCREF(Py_None);
6325 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00006326}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00006328
Guido van Rossum687dd131993-05-17 08:34:16 +00006329/* Functions acting on file descriptors */
6330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006332"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006333Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006334
Barry Warsaw53699e91996-12-10 23:23:01 +00006335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006336posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006337{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006338 char *file = NULL;
6339 int flag;
6340 int mode = 0777;
6341 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006342
6343#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006344 PyUnicodeObject *po;
6345 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6346 Py_BEGIN_ALLOW_THREADS
6347 /* PyUnicode_AS_UNICODE OK without thread
6348 lock as it is a simple dereference. */
6349 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6350 Py_END_ALLOW_THREADS
6351 if (fd < 0)
6352 return posix_error();
6353 return PyInt_FromLong((long)fd);
6354 }
6355 /* Drop the argument parsing error as narrow strings
6356 are also valid. */
6357 PyErr_Clear();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006358#endif
6359
Victor Stinnerd6f85422010-05-05 23:33:33 +00006360 if (!PyArg_ParseTuple(args, "eti|i",
6361 Py_FileSystemDefaultEncoding, &file,
6362 &flag, &mode))
6363 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006364
Victor Stinnerd6f85422010-05-05 23:33:33 +00006365 Py_BEGIN_ALLOW_THREADS
6366 fd = open(file, flag, mode);
6367 Py_END_ALLOW_THREADS
6368 if (fd < 0)
6369 return posix_error_with_allocated_filename(file);
6370 PyMem_Free(file);
6371 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006372}
6373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006377Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006378
Barry Warsaw53699e91996-12-10 23:23:01 +00006379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006380posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006381{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006382 int fd, res;
6383 if (!PyArg_ParseTuple(args, "i:close", &fd))
6384 return NULL;
6385 if (!_PyVerify_fd(fd))
6386 return posix_error();
6387 Py_BEGIN_ALLOW_THREADS
6388 res = close(fd);
6389 Py_END_ALLOW_THREADS
6390 if (res < 0)
6391 return posix_error();
6392 Py_INCREF(Py_None);
6393 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006394}
6395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006396
Victor Stinnerd6f85422010-05-05 23:33:33 +00006397PyDoc_STRVAR(posix_closerange__doc__,
Georg Brandl309501a2008-01-19 20:22:13 +00006398"closerange(fd_low, fd_high)\n\n\
6399Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6400
6401static PyObject *
6402posix_closerange(PyObject *self, PyObject *args)
6403{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006404 int fd_from, fd_to, i;
6405 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6406 return NULL;
6407 Py_BEGIN_ALLOW_THREADS
6408 for (i = fd_from; i < fd_to; i++)
6409 if (_PyVerify_fd(i))
6410 close(i);
6411 Py_END_ALLOW_THREADS
6412 Py_RETURN_NONE;
Georg Brandl309501a2008-01-19 20:22:13 +00006413}
6414
6415
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006416PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006417"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006419
Barry Warsaw53699e91996-12-10 23:23:01 +00006420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006421posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006422{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006423 int fd;
6424 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6425 return NULL;
6426 if (!_PyVerify_fd(fd))
6427 return posix_error();
6428 Py_BEGIN_ALLOW_THREADS
6429 fd = dup(fd);
6430 Py_END_ALLOW_THREADS
6431 if (fd < 0)
6432 return posix_error();
6433 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00006434}
6435
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006437PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00006438"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Barry Warsaw53699e91996-12-10 23:23:01 +00006441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006442posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006443{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006444 int fd, fd2, res;
6445 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6446 return NULL;
6447 if (!_PyVerify_fd_dup2(fd, fd2))
6448 return posix_error();
6449 Py_BEGIN_ALLOW_THREADS
6450 res = dup2(fd, fd2);
6451 Py_END_ALLOW_THREADS
6452 if (res < 0)
6453 return posix_error();
6454 Py_INCREF(Py_None);
6455 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00006456}
6457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006458
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006460"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006461Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006462
Barry Warsaw53699e91996-12-10 23:23:01 +00006463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006464posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006465{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006466 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006467#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006468 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006469#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006470 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00006471#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006472 PyObject *posobj;
6473 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6474 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00006475#ifdef SEEK_SET
Victor Stinnerd6f85422010-05-05 23:33:33 +00006476 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6477 switch (how) {
6478 case 0: how = SEEK_SET; break;
6479 case 1: how = SEEK_CUR; break;
6480 case 2: how = SEEK_END; break;
6481 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006482#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006483
6484#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006485 pos = PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006486#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006487 pos = PyLong_Check(posobj) ?
6488 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006489#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006490 if (PyErr_Occurred())
6491 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006492
Victor Stinnerd6f85422010-05-05 23:33:33 +00006493 if (!_PyVerify_fd(fd))
6494 return posix_error();
6495 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006496#if defined(MS_WIN64) || defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006497 res = _lseeki64(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006498#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006499 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00006500#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006501 Py_END_ALLOW_THREADS
6502 if (res < 0)
6503 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00006504
6505#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006506 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006507#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006508 return PyLong_FromLongLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006509#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006510}
6511
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006513PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006514"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006516
Barry Warsaw53699e91996-12-10 23:23:01 +00006517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006518posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006519{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006520 int fd, size, n;
6521 PyObject *buffer;
6522 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6523 return NULL;
6524 if (size < 0) {
6525 errno = EINVAL;
6526 return posix_error();
6527 }
6528 buffer = PyString_FromStringAndSize((char *)NULL, size);
6529 if (buffer == NULL)
6530 return NULL;
6531 if (!_PyVerify_fd(fd))
6532 return posix_error();
6533 Py_BEGIN_ALLOW_THREADS
6534 n = read(fd, PyString_AsString(buffer), size);
6535 Py_END_ALLOW_THREADS
6536 if (n < 0) {
6537 Py_DECREF(buffer);
6538 return posix_error();
6539 }
6540 if (n != size)
6541 _PyString_Resize(&buffer, n);
6542 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00006543}
6544
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006545
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006546PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006547"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006548Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006549
Barry Warsaw53699e91996-12-10 23:23:01 +00006550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006551posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006552{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006553 Py_buffer pbuf;
6554 int fd;
6555 Py_ssize_t size;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00006556
Victor Stinnerd6f85422010-05-05 23:33:33 +00006557 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6558 return NULL;
6559 if (!_PyVerify_fd(fd))
6560 return posix_error();
6561 Py_BEGIN_ALLOW_THREADS
6562 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6563 Py_END_ALLOW_THREADS
6564 PyBuffer_Release(&pbuf);
6565 if (size < 0)
6566 return posix_error();
6567 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006568}
6569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006572"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006573Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006574
Barry Warsaw53699e91996-12-10 23:23:01 +00006575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006576posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006577{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006578 int fd;
6579 STRUCT_STAT st;
6580 int res;
6581 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6582 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006583#ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006584 /* on OpenVMS we must ensure that all bytes are written to the file */
6585 fsync(fd);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006586#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006587 if (!_PyVerify_fd(fd))
6588 return posix_error();
6589 Py_BEGIN_ALLOW_THREADS
6590 res = FSTAT(fd, &st);
6591 Py_END_ALLOW_THREADS
6592 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00006593#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00006594 return win32_error("fstat", NULL);
Martin v. Löwis14694662006-02-03 12:54:16 +00006595#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006596 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006597#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006598 }
Tim Peters5aa91602002-01-30 05:46:57 +00006599
Victor Stinnerd6f85422010-05-05 23:33:33 +00006600 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006601}
6602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006604PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006605"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006606Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006607
Barry Warsaw53699e91996-12-10 23:23:01 +00006608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006609posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006610{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006611 int fd;
6612 char *orgmode = "r";
6613 int bufsize = -1;
6614 FILE *fp;
6615 PyObject *f;
6616 char *mode;
6617 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6618 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006619
Victor Stinnerd6f85422010-05-05 23:33:33 +00006620 /* Sanitize mode. See fileobject.c */
6621 mode = PyMem_MALLOC(strlen(orgmode)+3);
6622 if (!mode) {
6623 PyErr_NoMemory();
6624 return NULL;
6625 }
6626 strcpy(mode, orgmode);
6627 if (_PyFile_SanitizeMode(mode)) {
6628 PyMem_FREE(mode);
6629 return NULL;
6630 }
6631 if (!_PyVerify_fd(fd))
6632 return posix_error();
6633 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006634#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006635 if (mode[0] == 'a') {
6636 /* try to make sure the O_APPEND flag is set */
6637 int flags;
6638 flags = fcntl(fd, F_GETFL);
6639 if (flags != -1)
6640 fcntl(fd, F_SETFL, flags | O_APPEND);
6641 fp = fdopen(fd, mode);
6642 if (fp == NULL && flags != -1)
6643 /* restore old mode if fdopen failed */
6644 fcntl(fd, F_SETFL, flags);
6645 } else {
6646 fp = fdopen(fd, mode);
6647 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006648#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006649 fp = fdopen(fd, mode);
Georg Brandl644b1e72006-03-31 20:27:22 +00006650#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006651 Py_END_ALLOW_THREADS
6652 PyMem_FREE(mode);
6653 if (fp == NULL)
6654 return posix_error();
6655 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6656 if (f != NULL)
6657 PyFile_SetBufSize(f, bufsize);
6658 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006659}
6660
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006661PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006662"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006663Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006664connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006665
6666static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006667posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006668{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006669 int fd;
6670 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6671 return NULL;
6672 if (!_PyVerify_fd(fd))
6673 return PyBool_FromLong(0);
6674 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006675}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006676
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006677#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006678PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006679"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006680Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006681
Barry Warsaw53699e91996-12-10 23:23:01 +00006682static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006683posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006684{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006685#if defined(PYOS_OS2)
6686 HFILE read, write;
6687 APIRET rc;
6688
Victor Stinnerd6f85422010-05-05 23:33:33 +00006689 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006690 rc = DosCreatePipe( &read, &write, 4096);
Victor Stinnerd6f85422010-05-05 23:33:33 +00006691 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006692 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006693 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006694
6695 return Py_BuildValue("(ii)", read, write);
6696#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006697#if !defined(MS_WINDOWS)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006698 int fds[2];
6699 int res;
6700 Py_BEGIN_ALLOW_THREADS
6701 res = pipe(fds);
6702 Py_END_ALLOW_THREADS
6703 if (res != 0)
6704 return posix_error();
6705 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006706#else /* MS_WINDOWS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00006707 HANDLE read, write;
6708 int read_fd, write_fd;
6709 BOOL ok;
6710 Py_BEGIN_ALLOW_THREADS
6711 ok = CreatePipe(&read, &write, NULL, 0);
6712 Py_END_ALLOW_THREADS
6713 if (!ok)
6714 return win32_error("CreatePipe", NULL);
6715 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6716 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6717 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006718#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006719#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006720}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006721#endif /* HAVE_PIPE */
6722
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006723
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006724#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006725PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006726"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006727Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006728
Barry Warsaw53699e91996-12-10 23:23:01 +00006729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006730posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006731{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006732 char *filename;
6733 int mode = 0666;
6734 int res;
6735 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6736 return NULL;
6737 Py_BEGIN_ALLOW_THREADS
6738 res = mkfifo(filename, mode);
6739 Py_END_ALLOW_THREADS
6740 if (res < 0)
6741 return posix_error();
6742 Py_INCREF(Py_None);
6743 return Py_None;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006744}
6745#endif
6746
6747
Neal Norwitz11690112002-07-30 01:08:28 +00006748#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006750"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006751Create a filesystem node (file, device special file or named pipe)\n\
6752named filename. mode specifies both the permissions to use and the\n\
6753type of node to be created, being combined (bitwise OR) with one of\n\
6754S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006755device defines the newly created device special file (probably using\n\
6756os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006757
6758
6759static PyObject *
6760posix_mknod(PyObject *self, PyObject *args)
6761{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006762 char *filename;
6763 int mode = 0600;
6764 int device = 0;
6765 int res;
6766 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6767 return NULL;
6768 Py_BEGIN_ALLOW_THREADS
6769 res = mknod(filename, mode, device);
6770 Py_END_ALLOW_THREADS
6771 if (res < 0)
6772 return posix_error();
6773 Py_INCREF(Py_None);
6774 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006775}
6776#endif
6777
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006778#ifdef HAVE_DEVICE_MACROS
6779PyDoc_STRVAR(posix_major__doc__,
6780"major(device) -> major number\n\
6781Extracts a device major number from a raw device number.");
6782
6783static PyObject *
6784posix_major(PyObject *self, PyObject *args)
6785{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006786 int device;
6787 if (!PyArg_ParseTuple(args, "i:major", &device))
6788 return NULL;
6789 return PyInt_FromLong((long)major(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006790}
6791
6792PyDoc_STRVAR(posix_minor__doc__,
6793"minor(device) -> minor number\n\
6794Extracts a device minor number from a raw device number.");
6795
6796static PyObject *
6797posix_minor(PyObject *self, PyObject *args)
6798{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006799 int device;
6800 if (!PyArg_ParseTuple(args, "i:minor", &device))
6801 return NULL;
6802 return PyInt_FromLong((long)minor(device));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006803}
6804
6805PyDoc_STRVAR(posix_makedev__doc__,
6806"makedev(major, minor) -> device number\n\
6807Composes a raw device number from the major and minor device numbers.");
6808
6809static PyObject *
6810posix_makedev(PyObject *self, PyObject *args)
6811{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006812 int major, minor;
6813 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6814 return NULL;
6815 return PyInt_FromLong((long)makedev(major, minor));
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006816}
6817#endif /* device macros */
6818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006819
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006820#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006821PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006822"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006823Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006824
Barry Warsaw53699e91996-12-10 23:23:01 +00006825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006826posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006827{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006828 int fd;
6829 off_t length;
6830 int res;
6831 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006832
Victor Stinnerd6f85422010-05-05 23:33:33 +00006833 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6834 return NULL;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006835
6836#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00006837 length = PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006838#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00006839 length = PyLong_Check(lenobj) ?
6840 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006841#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006842 if (PyErr_Occurred())
6843 return NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006844
Victor Stinnerd6f85422010-05-05 23:33:33 +00006845 Py_BEGIN_ALLOW_THREADS
6846 res = ftruncate(fd, length);
6847 Py_END_ALLOW_THREADS
6848 if (res < 0)
6849 return posix_error();
6850 Py_INCREF(Py_None);
6851 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006852}
6853#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006854
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006855#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006856PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006857"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006859
Fred Drake762e2061999-08-26 17:23:54 +00006860/* Save putenv() parameters as values here, so we can collect them when they
6861 * get re-set with another call for the same key. */
6862static PyObject *posix_putenv_garbage;
6863
Tim Peters5aa91602002-01-30 05:46:57 +00006864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006865posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006866{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006867 char *s1, *s2;
6868 char *newenv;
6869 PyObject *newstr;
6870 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006871
Victor Stinnerd6f85422010-05-05 23:33:33 +00006872 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6873 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006874
6875#if defined(PYOS_OS2)
6876 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6877 APIRET rc;
6878
Guido van Rossumd48f2521997-12-05 22:19:34 +00006879 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6880 if (rc != NO_ERROR)
6881 return os2_error(rc);
6882
6883 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6884 APIRET rc;
6885
Guido van Rossumd48f2521997-12-05 22:19:34 +00006886 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6887 if (rc != NO_ERROR)
6888 return os2_error(rc);
6889 } else {
6890#endif
6891
Victor Stinnerd6f85422010-05-05 23:33:33 +00006892 /* XXX This can leak memory -- not easy to fix :-( */
6893 len = strlen(s1) + strlen(s2) + 2;
6894 /* len includes space for a trailing \0; the size arg to
6895 PyString_FromStringAndSize does not count that */
6896 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6897 if (newstr == NULL)
6898 return PyErr_NoMemory();
6899 newenv = PyString_AS_STRING(newstr);
6900 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6901 if (putenv(newenv)) {
6902 Py_DECREF(newstr);
6903 posix_error();
6904 return NULL;
6905 }
6906 /* Install the first arg and newstr in posix_putenv_garbage;
6907 * this will cause previous value to be collected. This has to
6908 * happen after the real putenv() call because the old value
6909 * was still accessible until then. */
6910 if (PyDict_SetItem(posix_putenv_garbage,
6911 PyTuple_GET_ITEM(args, 0), newstr)) {
6912 /* really not much we can do; just leak */
6913 PyErr_Clear();
6914 }
6915 else {
6916 Py_DECREF(newstr);
6917 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006918
6919#if defined(PYOS_OS2)
6920 }
6921#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00006922 Py_INCREF(Py_None);
6923 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006924}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006925#endif /* putenv */
6926
Guido van Rossumc524d952001-10-19 01:31:59 +00006927#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006928PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006929"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006930Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006931
6932static PyObject *
6933posix_unsetenv(PyObject *self, PyObject *args)
6934{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006935 char *s1;
Guido van Rossumc524d952001-10-19 01:31:59 +00006936
Victor Stinnerd6f85422010-05-05 23:33:33 +00006937 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6938 return NULL;
Guido van Rossumc524d952001-10-19 01:31:59 +00006939
Victor Stinnerd6f85422010-05-05 23:33:33 +00006940 unsetenv(s1);
Guido van Rossumc524d952001-10-19 01:31:59 +00006941
Victor Stinnerd6f85422010-05-05 23:33:33 +00006942 /* Remove the key from posix_putenv_garbage;
6943 * this will cause it to be collected. This has to
6944 * happen after the real unsetenv() call because the
6945 * old value was still accessible until then.
6946 */
6947 if (PyDict_DelItem(posix_putenv_garbage,
6948 PyTuple_GET_ITEM(args, 0))) {
6949 /* really not much we can do; just leak */
6950 PyErr_Clear();
6951 }
Guido van Rossumc524d952001-10-19 01:31:59 +00006952
Victor Stinnerd6f85422010-05-05 23:33:33 +00006953 Py_INCREF(Py_None);
6954 return Py_None;
Guido van Rossumc524d952001-10-19 01:31:59 +00006955}
6956#endif /* unsetenv */
6957
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006958PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006959"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006960Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006961
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006963posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006964{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006965 int code;
6966 char *message;
6967 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6968 return NULL;
6969 message = strerror(code);
6970 if (message == NULL) {
6971 PyErr_SetString(PyExc_ValueError,
6972 "strerror() argument out of range");
6973 return NULL;
6974 }
6975 return PyString_FromString(message);
Guido van Rossumb6a47161997-09-15 22:54:34 +00006976}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006977
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006978
Guido van Rossumc9641791998-08-04 15:26:23 +00006979#ifdef HAVE_SYS_WAIT_H
6980
Fred Drake106c1a02002-04-23 15:58:02 +00006981#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006982PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006983"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006984Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006985
6986static PyObject *
6987posix_WCOREDUMP(PyObject *self, PyObject *args)
6988{
Victor Stinnerd6f85422010-05-05 23:33:33 +00006989 WAIT_TYPE status;
6990 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006991
Victor Stinnerd6f85422010-05-05 23:33:33 +00006992 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6993 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006994
Victor Stinnerd6f85422010-05-05 23:33:33 +00006995 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006996}
6997#endif /* WCOREDUMP */
6998
6999#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007000PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007001"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00007002Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007003job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00007004
7005static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007006posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00007007{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007008 WAIT_TYPE status;
7009 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00007010
Victor Stinnerd6f85422010-05-05 23:33:33 +00007011 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
7012 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00007013
Victor Stinnerd6f85422010-05-05 23:33:33 +00007014 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00007015}
7016#endif /* WIFCONTINUED */
7017
Guido van Rossumc9641791998-08-04 15:26:23 +00007018#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007019PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007020"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007021Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007022
7023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007024posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007025{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007026 WAIT_TYPE status;
7027 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007028
Victor Stinnerd6f85422010-05-05 23:33:33 +00007029 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
7030 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007031
Victor Stinnerd6f85422010-05-05 23:33:33 +00007032 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007033}
7034#endif /* WIFSTOPPED */
7035
7036#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007037PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007038"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007039Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007040
7041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007042posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007043{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007044 WAIT_TYPE status;
7045 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007046
Victor Stinnerd6f85422010-05-05 23:33:33 +00007047 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
7048 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007049
Victor Stinnerd6f85422010-05-05 23:33:33 +00007050 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007051}
7052#endif /* WIFSIGNALED */
7053
7054#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007055PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007056"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007057Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007058system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007059
7060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007061posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007062{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007063 WAIT_TYPE status;
7064 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007065
Victor Stinnerd6f85422010-05-05 23:33:33 +00007066 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
7067 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007068
Victor Stinnerd6f85422010-05-05 23:33:33 +00007069 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007070}
7071#endif /* WIFEXITED */
7072
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007073#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007074PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007075"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007077
7078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007079posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007080{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007081 WAIT_TYPE status;
7082 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007083
Victor Stinnerd6f85422010-05-05 23:33:33 +00007084 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
7085 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007086
Victor Stinnerd6f85422010-05-05 23:33:33 +00007087 return Py_BuildValue("i", WEXITSTATUS(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007088}
7089#endif /* WEXITSTATUS */
7090
7091#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007092PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007093"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00007094Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007095value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007096
7097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007098posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007099{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007100 WAIT_TYPE status;
7101 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007102
Victor Stinnerd6f85422010-05-05 23:33:33 +00007103 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
7104 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007105
Victor Stinnerd6f85422010-05-05 23:33:33 +00007106 return Py_BuildValue("i", WTERMSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007107}
7108#endif /* WTERMSIG */
7109
7110#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007111PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007112"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007113Return the signal that stopped the process that provided\n\
7114the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00007115
7116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007117posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00007118{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007119 WAIT_TYPE status;
7120 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00007121
Victor Stinnerd6f85422010-05-05 23:33:33 +00007122 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
7123 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00007124
Victor Stinnerd6f85422010-05-05 23:33:33 +00007125 return Py_BuildValue("i", WSTOPSIG(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00007126}
7127#endif /* WSTOPSIG */
7128
7129#endif /* HAVE_SYS_WAIT_H */
7130
7131
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007132#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00007133#ifdef _SCO_DS
7134/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
7135 needed definitions in sys/statvfs.h */
7136#define _SVID3
7137#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007138#include <sys/statvfs.h>
7139
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007140static PyObject*
7141_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007142 PyObject *v = PyStructSequence_New(&StatVFSResultType);
7143 if (v == NULL)
7144 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007145
7146#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007147 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7148 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7149 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
7150 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
7151 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
7152 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
7153 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
7154 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
7155 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7156 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007157#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007158 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
7159 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
7160 PyStructSequence_SET_ITEM(v, 2,
7161 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
7162 PyStructSequence_SET_ITEM(v, 3,
7163 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
7164 PyStructSequence_SET_ITEM(v, 4,
7165 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
7166 PyStructSequence_SET_ITEM(v, 5,
7167 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
7168 PyStructSequence_SET_ITEM(v, 6,
7169 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
7170 PyStructSequence_SET_ITEM(v, 7,
7171 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
7172 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
7173 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007174#endif
7175
Victor Stinnerd6f85422010-05-05 23:33:33 +00007176 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007177}
7178
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007179PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007180"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007181Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007182
7183static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007184posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007185{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007186 int fd, res;
7187 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007188
Victor Stinnerd6f85422010-05-05 23:33:33 +00007189 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
7190 return NULL;
7191 Py_BEGIN_ALLOW_THREADS
7192 res = fstatvfs(fd, &st);
7193 Py_END_ALLOW_THREADS
7194 if (res != 0)
7195 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007196
Victor Stinnerd6f85422010-05-05 23:33:33 +00007197 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007198}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007199#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007200
7201
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00007202#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007203#include <sys/statvfs.h>
7204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007205PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007206"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007207Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00007208
7209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007210posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00007211{
Victor Stinnerd6f85422010-05-05 23:33:33 +00007212 char *path;
7213 int res;
7214 struct statvfs st;
7215 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7216 return NULL;
7217 Py_BEGIN_ALLOW_THREADS
7218 res = statvfs(path, &st);
7219 Py_END_ALLOW_THREADS
7220 if (res != 0)
7221 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007222
Victor Stinnerd6f85422010-05-05 23:33:33 +00007223 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00007224}
7225#endif /* HAVE_STATVFS */
7226
7227
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007228#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007229PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007230"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007231Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00007232The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007233or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007234
7235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007236posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007237{
7238 PyObject *result = NULL;
7239 char *dir = NULL;
7240 char *pfx = NULL;
7241 char *name;
7242
7243 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
Victor Stinnerd6f85422010-05-05 23:33:33 +00007244 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007245
7246 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007247 "tempnam is a potential security risk to your program") < 0)
7248 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007249
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007250#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00007251 name = _tempnam(dir, pfx);
7252#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007253 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00007254#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007255 if (name == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007256 return PyErr_NoMemory();
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007257 result = PyString_FromString(name);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007258 free(name);
7259 return result;
7260}
Guido van Rossumd371ff11999-01-25 16:12:23 +00007261#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007262
7263
7264#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007265PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007266"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007267Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007268
7269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007270posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007271{
7272 FILE *fp;
7273
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007274 fp = tmpfile();
7275 if (fp == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00007276 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00007277 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007278}
7279#endif
7280
7281
7282#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007283PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007284"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007285Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007286
7287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007288posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007289{
7290 char buffer[L_tmpnam];
7291 char *name;
7292
Skip Montanaro95618b52001-08-18 18:52:10 +00007293 if (PyErr_Warn(PyExc_RuntimeWarning,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007294 "tmpnam is a potential security risk to your program") < 0)
7295 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00007296
Greg Wardb48bc172000-03-01 21:51:56 +00007297#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007298 name = tmpnam_r(buffer);
7299#else
7300 name = tmpnam(buffer);
7301#endif
7302 if (name == NULL) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007303 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00007304#ifdef USE_TMPNAM_R
Victor Stinnerd6f85422010-05-05 23:33:33 +00007305 "unexpected NULL from tmpnam_r"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007306#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007307 "unexpected NULL from tmpnam"
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007308#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00007309 );
7310 PyErr_SetObject(PyExc_OSError, err);
7311 Py_XDECREF(err);
7312 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007313 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007314 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007315}
7316#endif
7317
7318
Fred Drakec9680921999-12-13 16:37:25 +00007319/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7320 * It maps strings representing configuration variable names to
7321 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00007322 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00007323 * rarely-used constants. There are three separate tables that use
7324 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00007325 *
7326 * This code is always included, even if none of the interfaces that
7327 * need it are included. The #if hackery needed to avoid it would be
7328 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00007329 */
7330struct constdef {
7331 char *name;
7332 long value;
7333};
7334
Fred Drake12c6e2d1999-12-14 21:25:03 +00007335static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007336conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Victor Stinnerd6f85422010-05-05 23:33:33 +00007337 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00007338{
7339 if (PyInt_Check(arg)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007340 *valuep = PyInt_AS_LONG(arg);
7341 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007342 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +00007343 if (PyString_Check(arg)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007344 /* look up the value in the table using a binary search */
7345 size_t lo = 0;
7346 size_t mid;
7347 size_t hi = tablesize;
7348 int cmp;
7349 char *confname = PyString_AS_STRING(arg);
7350 while (lo < hi) {
7351 mid = (lo + hi) / 2;
7352 cmp = strcmp(confname, table[mid].name);
7353 if (cmp < 0)
7354 hi = mid;
7355 else if (cmp > 0)
7356 lo = mid + 1;
7357 else {
7358 *valuep = table[mid].value;
7359 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00007360 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007361 }
7362 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007363 }
7364 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007365 PyErr_SetString(PyExc_TypeError,
7366 "configuration names must be strings or integers");
Fred Drake12c6e2d1999-12-14 21:25:03 +00007367 return 0;
7368}
7369
7370
7371#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7372static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007373#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007374 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007375#endif
7376#ifdef _PC_ABI_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007377 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007378#endif
Fred Drakec9680921999-12-13 16:37:25 +00007379#ifdef _PC_ASYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007380 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007381#endif
7382#ifdef _PC_CHOWN_RESTRICTED
Victor Stinnerd6f85422010-05-05 23:33:33 +00007383 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00007384#endif
7385#ifdef _PC_FILESIZEBITS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007386 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00007387#endif
7388#ifdef _PC_LAST
Victor Stinnerd6f85422010-05-05 23:33:33 +00007389 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00007390#endif
7391#ifdef _PC_LINK_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007392 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007393#endif
7394#ifdef _PC_MAX_CANON
Victor Stinnerd6f85422010-05-05 23:33:33 +00007395 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00007396#endif
7397#ifdef _PC_MAX_INPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007398 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00007399#endif
7400#ifdef _PC_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007401 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007402#endif
7403#ifdef _PC_NO_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007404 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00007405#endif
7406#ifdef _PC_PATH_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007407 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007408#endif
7409#ifdef _PC_PIPE_BUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007410 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00007411#endif
7412#ifdef _PC_PRIO_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007413 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007414#endif
7415#ifdef _PC_SOCK_MAXBUF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007416 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00007417#endif
7418#ifdef _PC_SYNC_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007419 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007420#endif
7421#ifdef _PC_VDISABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007422 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00007423#endif
7424};
7425
Fred Drakec9680921999-12-13 16:37:25 +00007426static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007427conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007428{
7429 return conv_confname(arg, valuep, posix_constants_pathconf,
7430 sizeof(posix_constants_pathconf)
7431 / sizeof(struct constdef));
7432}
7433#endif
7434
7435#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007436PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007437"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007438Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007439If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007440
7441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007442posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007443{
7444 PyObject *result = NULL;
7445 int name, fd;
7446
Fred Drake12c6e2d1999-12-14 21:25:03 +00007447 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7448 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007449 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007450
Victor Stinnerd6f85422010-05-05 23:33:33 +00007451 errno = 0;
7452 limit = fpathconf(fd, name);
7453 if (limit == -1 && errno != 0)
7454 posix_error();
7455 else
7456 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007457 }
7458 return result;
7459}
7460#endif
7461
7462
7463#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007464PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007465"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00007466Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007467If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00007468
7469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007470posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007471{
7472 PyObject *result = NULL;
7473 int name;
7474 char *path;
7475
7476 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7477 conv_path_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007478 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00007479
Victor Stinnerd6f85422010-05-05 23:33:33 +00007480 errno = 0;
7481 limit = pathconf(path, name);
7482 if (limit == -1 && errno != 0) {
7483 if (errno == EINVAL)
7484 /* could be a path or name problem */
7485 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007486 else
Victor Stinnerd6f85422010-05-05 23:33:33 +00007487 posix_error_with_filename(path);
7488 }
7489 else
7490 result = PyInt_FromLong(limit);
Fred Drakec9680921999-12-13 16:37:25 +00007491 }
7492 return result;
7493}
7494#endif
7495
7496#ifdef HAVE_CONFSTR
7497static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00007498#ifdef _CS_ARCHITECTURE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007499 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00007500#endif
7501#ifdef _CS_HOSTNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007502 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007503#endif
7504#ifdef _CS_HW_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007505 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007506#endif
7507#ifdef _CS_HW_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007508 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007509#endif
7510#ifdef _CS_INITTAB_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007511 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007512#endif
Fred Drakec9680921999-12-13 16:37:25 +00007513#ifdef _CS_LFS64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007514 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007515#endif
7516#ifdef _CS_LFS64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007517 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007518#endif
7519#ifdef _CS_LFS64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007520 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007521#endif
7522#ifdef _CS_LFS64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007523 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007524#endif
7525#ifdef _CS_LFS_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007526 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007527#endif
7528#ifdef _CS_LFS_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007529 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007530#endif
7531#ifdef _CS_LFS_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007532 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007533#endif
7534#ifdef _CS_LFS_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007535 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007536#endif
Fred Draked86ed291999-12-15 15:34:33 +00007537#ifdef _CS_MACHINE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007538 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00007539#endif
Fred Drakec9680921999-12-13 16:37:25 +00007540#ifdef _CS_PATH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007541 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00007542#endif
Fred Draked86ed291999-12-15 15:34:33 +00007543#ifdef _CS_RELEASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007544 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00007545#endif
7546#ifdef _CS_SRPC_DOMAIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007547 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00007548#endif
7549#ifdef _CS_SYSNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007550 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00007551#endif
7552#ifdef _CS_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007553 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00007554#endif
Fred Drakec9680921999-12-13 16:37:25 +00007555#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007556 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007557#endif
7558#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007559 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007560#endif
7561#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007562 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007563#endif
7564#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007565 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007566#endif
7567#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007568 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007569#endif
7570#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007571 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007572#endif
7573#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007574 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007575#endif
7576#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007577 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007578#endif
7579#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007580 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007581#endif
7582#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007583 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007584#endif
7585#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007586 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007587#endif
7588#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007589 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007590#endif
7591#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007592 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007593#endif
7594#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007595 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007596#endif
7597#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007598 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00007599#endif
7600#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007601 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00007602#endif
Fred Draked86ed291999-12-15 15:34:33 +00007603#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007604 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007605#endif
7606#ifdef _MIPS_CS_BASE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007607 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00007608#endif
7609#ifdef _MIPS_CS_HOSTID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007610 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00007611#endif
7612#ifdef _MIPS_CS_HW_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007613 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007614#endif
7615#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007616 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007617#endif
7618#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007619 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00007620#endif
7621#ifdef _MIPS_CS_OSREL_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007622 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00007623#endif
7624#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinnerd6f85422010-05-05 23:33:33 +00007625 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00007626#endif
7627#ifdef _MIPS_CS_OS_NAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00007628 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00007629#endif
7630#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinnerd6f85422010-05-05 23:33:33 +00007631 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00007632#endif
7633#ifdef _MIPS_CS_PROCESSORS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007634 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00007635#endif
7636#ifdef _MIPS_CS_SERIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007637 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00007638#endif
7639#ifdef _MIPS_CS_VENDOR
Victor Stinnerd6f85422010-05-05 23:33:33 +00007640 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00007641#endif
Fred Drakec9680921999-12-13 16:37:25 +00007642};
7643
7644static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007645conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007646{
7647 return conv_confname(arg, valuep, posix_constants_confstr,
7648 sizeof(posix_constants_confstr)
7649 / sizeof(struct constdef));
7650}
7651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007652PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007653"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007654Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007655
7656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007657posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007658{
7659 PyObject *result = NULL;
7660 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007661 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007662
7663 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007664 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007665
Victor Stinnerd6f85422010-05-05 23:33:33 +00007666 errno = 0;
7667 len = confstr(name, buffer, sizeof(buffer));
7668 if (len == 0) {
7669 if (errno) {
7670 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00007671 }
7672 else {
Victor Stinnerd6f85422010-05-05 23:33:33 +00007673 result = Py_None;
7674 Py_INCREF(Py_None);
Fred Drakec9680921999-12-13 16:37:25 +00007675 }
7676 }
Victor Stinnerd6f85422010-05-05 23:33:33 +00007677 else {
7678 if ((unsigned int)len >= sizeof(buffer)) {
7679 result = PyString_FromStringAndSize(NULL, len-1);
7680 if (result != NULL)
7681 confstr(name, PyString_AS_STRING(result), len);
7682 }
7683 else
7684 result = PyString_FromStringAndSize(buffer, len-1);
7685 }
7686 }
Fred Drakec9680921999-12-13 16:37:25 +00007687 return result;
7688}
7689#endif
7690
7691
7692#ifdef HAVE_SYSCONF
7693static struct constdef posix_constants_sysconf[] = {
7694#ifdef _SC_2_CHAR_TERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007695 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00007696#endif
7697#ifdef _SC_2_C_BIND
Victor Stinnerd6f85422010-05-05 23:33:33 +00007698 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00007699#endif
7700#ifdef _SC_2_C_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007701 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007702#endif
7703#ifdef _SC_2_C_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007704 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007705#endif
7706#ifdef _SC_2_FORT_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007707 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007708#endif
7709#ifdef _SC_2_FORT_RUN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007710 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00007711#endif
7712#ifdef _SC_2_LOCALEDEF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007713 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00007714#endif
7715#ifdef _SC_2_SW_DEV
Victor Stinnerd6f85422010-05-05 23:33:33 +00007716 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00007717#endif
7718#ifdef _SC_2_UPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007719 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00007720#endif
7721#ifdef _SC_2_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007722 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00007723#endif
Fred Draked86ed291999-12-15 15:34:33 +00007724#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007725 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00007726#endif
7727#ifdef _SC_ACL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007728 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00007729#endif
Fred Drakec9680921999-12-13 16:37:25 +00007730#ifdef _SC_AIO_LISTIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007731 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007732#endif
Fred Drakec9680921999-12-13 16:37:25 +00007733#ifdef _SC_AIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007734 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007735#endif
7736#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007737 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007738#endif
7739#ifdef _SC_ARG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007740 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007741#endif
7742#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007743 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007744#endif
7745#ifdef _SC_ATEXIT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007746 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007747#endif
Fred Draked86ed291999-12-15 15:34:33 +00007748#ifdef _SC_AUDIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007749 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00007750#endif
Fred Drakec9680921999-12-13 16:37:25 +00007751#ifdef _SC_AVPHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007752 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007753#endif
7754#ifdef _SC_BC_BASE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007755 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007756#endif
7757#ifdef _SC_BC_DIM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007758 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007759#endif
7760#ifdef _SC_BC_SCALE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007761 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007762#endif
7763#ifdef _SC_BC_STRING_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007764 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007765#endif
Fred Draked86ed291999-12-15 15:34:33 +00007766#ifdef _SC_CAP
Victor Stinnerd6f85422010-05-05 23:33:33 +00007767 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00007768#endif
Fred Drakec9680921999-12-13 16:37:25 +00007769#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007770 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007771#endif
7772#ifdef _SC_CHAR_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007773 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007774#endif
7775#ifdef _SC_CHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007776 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007777#endif
7778#ifdef _SC_CHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007779 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007780#endif
7781#ifdef _SC_CHILD_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007782 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007783#endif
7784#ifdef _SC_CLK_TCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007785 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00007786#endif
7787#ifdef _SC_COHER_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007788 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007789#endif
7790#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007791 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007792#endif
7793#ifdef _SC_DCACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007794 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007795#endif
7796#ifdef _SC_DCACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007797 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007798#endif
7799#ifdef _SC_DCACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007800 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007801#endif
7802#ifdef _SC_DCACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007803 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007804#endif
7805#ifdef _SC_DCACHE_TBLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007806 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007807#endif
7808#ifdef _SC_DELAYTIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007809 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007810#endif
7811#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007812 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007813#endif
7814#ifdef _SC_EXPR_NEST_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007815 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007816#endif
7817#ifdef _SC_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007818 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00007819#endif
7820#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007821 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007822#endif
7823#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007824 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007825#endif
7826#ifdef _SC_ICACHE_ASSOC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007827 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00007828#endif
7829#ifdef _SC_ICACHE_BLKSZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007830 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00007831#endif
7832#ifdef _SC_ICACHE_LINESZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007833 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00007834#endif
7835#ifdef _SC_ICACHE_SZ
Victor Stinnerd6f85422010-05-05 23:33:33 +00007836 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00007837#endif
Fred Draked86ed291999-12-15 15:34:33 +00007838#ifdef _SC_INF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007839 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00007840#endif
Fred Drakec9680921999-12-13 16:37:25 +00007841#ifdef _SC_INT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007842 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007843#endif
7844#ifdef _SC_INT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007845 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00007846#endif
7847#ifdef _SC_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007848 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007849#endif
Fred Draked86ed291999-12-15 15:34:33 +00007850#ifdef _SC_IP_SECOPTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007851 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00007852#endif
Fred Drakec9680921999-12-13 16:37:25 +00007853#ifdef _SC_JOB_CONTROL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007854 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00007855#endif
Fred Draked86ed291999-12-15 15:34:33 +00007856#ifdef _SC_KERN_POINTERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007857 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00007858#endif
7859#ifdef _SC_KERN_SIM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007860 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00007861#endif
Fred Drakec9680921999-12-13 16:37:25 +00007862#ifdef _SC_LINE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007863 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007864#endif
7865#ifdef _SC_LOGIN_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007866 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007867#endif
7868#ifdef _SC_LOGNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007869 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007870#endif
7871#ifdef _SC_LONG_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007872 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00007873#endif
Fred Draked86ed291999-12-15 15:34:33 +00007874#ifdef _SC_MAC
Victor Stinnerd6f85422010-05-05 23:33:33 +00007875 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00007876#endif
Fred Drakec9680921999-12-13 16:37:25 +00007877#ifdef _SC_MAPPED_FILES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007878 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00007879#endif
7880#ifdef _SC_MAXPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00007881 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00007882#endif
7883#ifdef _SC_MB_LEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007884 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007885#endif
7886#ifdef _SC_MEMLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00007887 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00007888#endif
7889#ifdef _SC_MEMLOCK_RANGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007890 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00007891#endif
7892#ifdef _SC_MEMORY_PROTECTION
Victor Stinnerd6f85422010-05-05 23:33:33 +00007893 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00007894#endif
7895#ifdef _SC_MESSAGE_PASSING
Victor Stinnerd6f85422010-05-05 23:33:33 +00007896 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00007897#endif
Fred Draked86ed291999-12-15 15:34:33 +00007898#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinnerd6f85422010-05-05 23:33:33 +00007899 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00007900#endif
Fred Drakec9680921999-12-13 16:37:25 +00007901#ifdef _SC_MQ_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007902 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007903#endif
7904#ifdef _SC_MQ_PRIO_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007905 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007906#endif
Fred Draked86ed291999-12-15 15:34:33 +00007907#ifdef _SC_NACLS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007908 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00007909#endif
Fred Drakec9680921999-12-13 16:37:25 +00007910#ifdef _SC_NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007911 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007912#endif
7913#ifdef _SC_NL_ARGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007914 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007915#endif
7916#ifdef _SC_NL_LANGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007917 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007918#endif
7919#ifdef _SC_NL_MSGMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007920 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007921#endif
7922#ifdef _SC_NL_NMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007923 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007924#endif
7925#ifdef _SC_NL_SETMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007926 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007927#endif
7928#ifdef _SC_NL_TEXTMAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007929 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00007930#endif
7931#ifdef _SC_NPROCESSORS_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007932 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00007933#endif
7934#ifdef _SC_NPROCESSORS_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007935 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00007936#endif
Fred Draked86ed291999-12-15 15:34:33 +00007937#ifdef _SC_NPROC_CONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00007938 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00007939#endif
7940#ifdef _SC_NPROC_ONLN
Victor Stinnerd6f85422010-05-05 23:33:33 +00007941 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00007942#endif
Fred Drakec9680921999-12-13 16:37:25 +00007943#ifdef _SC_NZERO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007944 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00007945#endif
7946#ifdef _SC_OPEN_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007947 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007948#endif
7949#ifdef _SC_PAGESIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007950 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007951#endif
7952#ifdef _SC_PAGE_SIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00007953 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00007954#endif
7955#ifdef _SC_PASS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00007956 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00007957#endif
7958#ifdef _SC_PHYS_PAGES
Victor Stinnerd6f85422010-05-05 23:33:33 +00007959 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00007960#endif
7961#ifdef _SC_PII
Victor Stinnerd6f85422010-05-05 23:33:33 +00007962 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00007963#endif
7964#ifdef _SC_PII_INTERNET
Victor Stinnerd6f85422010-05-05 23:33:33 +00007965 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00007966#endif
7967#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007968 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00007969#endif
7970#ifdef _SC_PII_INTERNET_STREAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00007971 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00007972#endif
7973#ifdef _SC_PII_OSI
Victor Stinnerd6f85422010-05-05 23:33:33 +00007974 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00007975#endif
7976#ifdef _SC_PII_OSI_CLTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007977 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00007978#endif
7979#ifdef _SC_PII_OSI_COTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00007980 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00007981#endif
7982#ifdef _SC_PII_OSI_M
Victor Stinnerd6f85422010-05-05 23:33:33 +00007983 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00007984#endif
7985#ifdef _SC_PII_SOCKET
Victor Stinnerd6f85422010-05-05 23:33:33 +00007986 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00007987#endif
7988#ifdef _SC_PII_XTI
Victor Stinnerd6f85422010-05-05 23:33:33 +00007989 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00007990#endif
7991#ifdef _SC_POLL
Victor Stinnerd6f85422010-05-05 23:33:33 +00007992 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00007993#endif
7994#ifdef _SC_PRIORITIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00007995 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00007996#endif
7997#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00007998 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00007999#endif
8000#ifdef _SC_REALTIME_SIGNALS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008001 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00008002#endif
8003#ifdef _SC_RE_DUP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008004 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008005#endif
8006#ifdef _SC_RTSIG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008007 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008008#endif
8009#ifdef _SC_SAVED_IDS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008010 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00008011#endif
8012#ifdef _SC_SCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008013 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008014#endif
8015#ifdef _SC_SCHAR_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008016 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008017#endif
8018#ifdef _SC_SELECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008019 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00008020#endif
8021#ifdef _SC_SEMAPHORES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008022 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00008023#endif
8024#ifdef _SC_SEM_NSEMS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008025 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008026#endif
8027#ifdef _SC_SEM_VALUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008028 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008029#endif
8030#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008031 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00008032#endif
8033#ifdef _SC_SHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008034 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008035#endif
8036#ifdef _SC_SHRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008037 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008038#endif
8039#ifdef _SC_SIGQUEUE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008040 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008041#endif
8042#ifdef _SC_SIGRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008043 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008044#endif
8045#ifdef _SC_SIGRT_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008046 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008047#endif
Fred Draked86ed291999-12-15 15:34:33 +00008048#ifdef _SC_SOFTPOWER
Victor Stinnerd6f85422010-05-05 23:33:33 +00008049 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00008050#endif
Fred Drakec9680921999-12-13 16:37:25 +00008051#ifdef _SC_SPLIT_CACHE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008052 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00008053#endif
8054#ifdef _SC_SSIZE_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008055 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008056#endif
8057#ifdef _SC_STACK_PROT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008058 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +00008059#endif
8060#ifdef _SC_STREAM_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008061 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008062#endif
8063#ifdef _SC_SYNCHRONIZED_IO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008064 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00008065#endif
8066#ifdef _SC_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008067 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008068#endif
8069#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008070 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +00008071#endif
8072#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008073 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +00008074#endif
8075#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008076 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008077#endif
8078#ifdef _SC_THREAD_KEYS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008079 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008080#endif
8081#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinnerd6f85422010-05-05 23:33:33 +00008082 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00008083#endif
8084#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008085 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +00008086#endif
8087#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008088 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +00008089#endif
8090#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008091 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +00008092#endif
8093#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008094 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +00008095#endif
8096#ifdef _SC_THREAD_STACK_MIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008097 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00008098#endif
8099#ifdef _SC_THREAD_THREADS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008100 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008101#endif
8102#ifdef _SC_TIMERS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008103 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +00008104#endif
8105#ifdef _SC_TIMER_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008106 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008107#endif
8108#ifdef _SC_TTY_NAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008109 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008110#endif
8111#ifdef _SC_TZNAME_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008112 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008113#endif
8114#ifdef _SC_T_IOV_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008115 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008116#endif
8117#ifdef _SC_UCHAR_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008118 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008119#endif
8120#ifdef _SC_UINT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008121 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008122#endif
8123#ifdef _SC_UIO_MAXIOV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008124 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +00008125#endif
8126#ifdef _SC_ULONG_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008127 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008128#endif
8129#ifdef _SC_USHRT_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008130 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00008131#endif
8132#ifdef _SC_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008133 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008134#endif
8135#ifdef _SC_WORD_BIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008136 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00008137#endif
8138#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinnerd6f85422010-05-05 23:33:33 +00008139 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +00008140#endif
8141#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008142 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008143#endif
8144#ifdef _SC_XBS5_LP64_OFF64
Victor Stinnerd6f85422010-05-05 23:33:33 +00008145 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +00008146#endif
8147#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008148 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +00008149#endif
8150#ifdef _SC_XOPEN_CRYPT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008151 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +00008152#endif
8153#ifdef _SC_XOPEN_ENH_I18N
Victor Stinnerd6f85422010-05-05 23:33:33 +00008154 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +00008155#endif
8156#ifdef _SC_XOPEN_LEGACY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008157 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +00008158#endif
8159#ifdef _SC_XOPEN_REALTIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008160 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +00008161#endif
8162#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008163 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +00008164#endif
8165#ifdef _SC_XOPEN_SHM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008166 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +00008167#endif
8168#ifdef _SC_XOPEN_UNIX
Victor Stinnerd6f85422010-05-05 23:33:33 +00008169 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +00008170#endif
8171#ifdef _SC_XOPEN_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008172 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008173#endif
8174#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinnerd6f85422010-05-05 23:33:33 +00008175 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00008176#endif
8177#ifdef _SC_XOPEN_XPG2
Victor Stinnerd6f85422010-05-05 23:33:33 +00008178 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +00008179#endif
8180#ifdef _SC_XOPEN_XPG3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008181 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +00008182#endif
8183#ifdef _SC_XOPEN_XPG4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008184 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +00008185#endif
8186};
8187
8188static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008189conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00008190{
8191 return conv_confname(arg, valuep, posix_constants_sysconf,
8192 sizeof(posix_constants_sysconf)
8193 / sizeof(struct constdef));
8194}
8195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008196PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008197"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008198Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00008199
8200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008201posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00008202{
8203 PyObject *result = NULL;
8204 int name;
8205
8206 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
Victor Stinner862490a2010-05-06 00:03:44 +00008207 int value;
Fred Drakec9680921999-12-13 16:37:25 +00008208
Victor Stinner862490a2010-05-06 00:03:44 +00008209 errno = 0;
8210 value = sysconf(name);
8211 if (value == -1 && errno != 0)
8212 posix_error();
8213 else
8214 result = PyInt_FromLong(value);
Fred Drakec9680921999-12-13 16:37:25 +00008215 }
8216 return result;
8217}
8218#endif
8219
8220
Fred Drakebec628d1999-12-15 18:31:10 +00008221/* This code is used to ensure that the tables of configuration value names
8222 * are in sorted order as required by conv_confname(), and also to build the
8223 * the exported dictionaries that are used to publish information about the
8224 * names available on the host platform.
8225 *
8226 * Sorting the table at runtime ensures that the table is properly ordered
8227 * when used, even for platforms we're not able to test on. It also makes
8228 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00008229 */
Fred Drakebec628d1999-12-15 18:31:10 +00008230
8231static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008232cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00008233{
8234 const struct constdef *c1 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008235 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +00008236 const struct constdef *c2 =
Victor Stinnerd6f85422010-05-05 23:33:33 +00008237 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +00008238
8239 return strcmp(c1->name, c2->name);
8240}
8241
8242static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00008243setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinnerd6f85422010-05-05 23:33:33 +00008244 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008245{
Fred Drakebec628d1999-12-15 18:31:10 +00008246 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00008247 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00008248
8249 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8250 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00008251 if (d == NULL)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008252 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008253
Barry Warsaw3155db32000-04-13 15:20:40 +00008254 for (i=0; i < tablesize; ++i) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008255 PyObject *o = PyInt_FromLong(table[i].value);
8256 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8257 Py_XDECREF(o);
8258 Py_DECREF(d);
8259 return -1;
8260 }
8261 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00008262 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008263 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00008264}
8265
Fred Drakebec628d1999-12-15 18:31:10 +00008266/* Return -1 on failure, 0 on success. */
8267static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008268setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00008269{
8270#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00008271 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00008272 sizeof(posix_constants_pathconf)
8273 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008274 "pathconf_names", module))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008275 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008276#endif
8277#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00008278 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00008279 sizeof(posix_constants_confstr)
8280 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008281 "confstr_names", module))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008282 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008283#endif
8284#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00008285 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00008286 sizeof(posix_constants_sysconf)
8287 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00008288 "sysconf_names", module))
Victor Stinnerd6f85422010-05-05 23:33:33 +00008289 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00008290#endif
Fred Drakebec628d1999-12-15 18:31:10 +00008291 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00008292}
Fred Draked86ed291999-12-15 15:34:33 +00008293
8294
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008295PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00008296"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008297Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008298in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008299
8300static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008301posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008302{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008303 abort();
8304 /*NOTREACHED*/
8305 Py_FatalError("abort() called from Python code didn't abort!");
8306 return NULL;
8307}
Fred Drakebec628d1999-12-15 18:31:10 +00008308
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008309#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008310PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00008311"startfile(filepath [, operation]) - Start a file with its associated\n\
8312application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008313\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00008314When \"operation\" is not specified or \"open\", this acts like\n\
8315double-clicking the file in Explorer, or giving the file name as an\n\
8316argument to the DOS \"start\" command: the file is opened with whatever\n\
8317application (if any) its extension is associated.\n\
8318When another \"operation\" is given, it specifies what should be done with\n\
8319the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00008320\n\
8321startfile returns as soon as the associated application is launched.\n\
8322There is no option to wait for the application to close, and no way\n\
8323to retrieve the application's exit status.\n\
8324\n\
8325The filepath is relative to the current directory. If you want to use\n\
8326an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00008327the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00008328
8329static PyObject *
8330win32_startfile(PyObject *self, PyObject *args)
8331{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008332 char *filepath;
8333 char *operation = NULL;
8334 HINSTANCE rc;
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008335
Victor Stinnerd6f85422010-05-05 23:33:33 +00008336 PyObject *unipath, *woperation = NULL;
8337 if (!PyArg_ParseTuple(args, "U|s:startfile",
8338 &unipath, &operation)) {
8339 PyErr_Clear();
8340 goto normal;
8341 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008342
Victor Stinnerd6f85422010-05-05 23:33:33 +00008343 if (operation) {
8344 woperation = PyUnicode_DecodeASCII(operation,
8345 strlen(operation), NULL);
8346 if (!woperation) {
8347 PyErr_Clear();
8348 operation = NULL;
8349 goto normal;
8350 }
8351 }
Hirokazu Yamamotoa3c56092009-06-28 10:23:00 +00008352
Victor Stinnerd6f85422010-05-05 23:33:33 +00008353 Py_BEGIN_ALLOW_THREADS
8354 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8355 PyUnicode_AS_UNICODE(unipath),
8356 NULL, NULL, SW_SHOWNORMAL);
8357 Py_END_ALLOW_THREADS
8358
8359 Py_XDECREF(woperation);
8360 if (rc <= (HINSTANCE)32) {
8361 PyObject *errval = win32_error_unicode("startfile",
8362 PyUnicode_AS_UNICODE(unipath));
8363 return errval;
8364 }
8365 Py_INCREF(Py_None);
8366 return Py_None;
Georg Brandlad89dc82006-04-03 12:26:26 +00008367
8368normal:
Victor Stinnerd6f85422010-05-05 23:33:33 +00008369 if (!PyArg_ParseTuple(args, "et|s:startfile",
8370 Py_FileSystemDefaultEncoding, &filepath,
8371 &operation))
8372 return NULL;
8373 Py_BEGIN_ALLOW_THREADS
8374 rc = ShellExecute((HWND)0, operation, filepath,
8375 NULL, NULL, SW_SHOWNORMAL);
8376 Py_END_ALLOW_THREADS
8377 if (rc <= (HINSTANCE)32) {
8378 PyObject *errval = win32_error("startfile", filepath);
8379 PyMem_Free(filepath);
8380 return errval;
8381 }
8382 PyMem_Free(filepath);
8383 Py_INCREF(Py_None);
8384 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +00008385}
Hirokazu Yamamotob24bb272009-05-17 02:52:09 +00008386#endif /* MS_WINDOWS */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008387
Martin v. Löwis438b5342002-12-27 10:16:42 +00008388#ifdef HAVE_GETLOADAVG
8389PyDoc_STRVAR(posix_getloadavg__doc__,
8390"getloadavg() -> (float, float, float)\n\n\
8391Return the number of processes in the system run queue averaged over\n\
8392the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8393was unobtainable");
8394
8395static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00008396posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00008397{
8398 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00008399 if (getloadavg(loadavg, 3)!=3) {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008400 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8401 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +00008402 } else
Victor Stinnerd6f85422010-05-05 23:33:33 +00008403 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +00008404}
8405#endif
8406
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008407#ifdef MS_WINDOWS
8408
8409PyDoc_STRVAR(win32_urandom__doc__,
8410"urandom(n) -> str\n\n\
8411Return a string of n random bytes suitable for cryptographic use.");
8412
8413typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8414 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8415 DWORD dwFlags );
8416typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8417 BYTE *pbBuffer );
8418
8419static CRYPTGENRANDOM pCryptGenRandom = NULL;
Martin v. Löwisaf699dd2007-09-04 09:51:57 +00008420/* This handle is never explicitly released. Instead, the operating
8421 system will release it when the process terminates. */
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008422static HCRYPTPROV hCryptProv = 0;
8423
Tim Peters4ad82172004-08-30 17:02:04 +00008424static PyObject*
8425win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008426{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008427 int howMany;
8428 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008429
Victor Stinnerd6f85422010-05-05 23:33:33 +00008430 /* Read arguments */
8431 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8432 return NULL;
8433 if (howMany < 0)
8434 return PyErr_Format(PyExc_ValueError,
8435 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008436
Victor Stinnerd6f85422010-05-05 23:33:33 +00008437 if (hCryptProv == 0) {
8438 HINSTANCE hAdvAPI32 = NULL;
8439 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008440
Victor Stinnerd6f85422010-05-05 23:33:33 +00008441 /* Obtain handle to the DLL containing CryptoAPI
8442 This should not fail */
8443 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8444 if(hAdvAPI32 == NULL)
8445 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008446
Victor Stinnerd6f85422010-05-05 23:33:33 +00008447 /* Obtain pointers to the CryptoAPI functions
8448 This will fail on some early versions of Win95 */
8449 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8450 hAdvAPI32,
8451 "CryptAcquireContextA");
8452 if (pCryptAcquireContext == NULL)
8453 return PyErr_Format(PyExc_NotImplementedError,
8454 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008455
Victor Stinnerd6f85422010-05-05 23:33:33 +00008456 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8457 hAdvAPI32, "CryptGenRandom");
8458 if (pCryptGenRandom == NULL)
8459 return PyErr_Format(PyExc_NotImplementedError,
8460 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008461
Victor Stinnerd6f85422010-05-05 23:33:33 +00008462 /* Acquire context */
8463 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8464 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8465 return win32_error("CryptAcquireContext", NULL);
8466 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008467
Victor Stinnerd6f85422010-05-05 23:33:33 +00008468 /* Allocate bytes */
8469 result = PyString_FromStringAndSize(NULL, howMany);
8470 if (result != NULL) {
8471 /* Get random data */
8472 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8473 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8474 PyString_AS_STRING(result))) {
8475 Py_DECREF(result);
8476 return win32_error("CryptGenRandom", NULL);
8477 }
8478 }
8479 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008480}
8481#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008482
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008483#ifdef __VMS
8484/* Use openssl random routine */
8485#include <openssl/rand.h>
8486PyDoc_STRVAR(vms_urandom__doc__,
8487"urandom(n) -> str\n\n\
8488Return a string of n random bytes suitable for cryptographic use.");
8489
8490static PyObject*
8491vms_urandom(PyObject *self, PyObject *args)
8492{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008493 int howMany;
8494 PyObject* result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008495
Victor Stinnerd6f85422010-05-05 23:33:33 +00008496 /* Read arguments */
8497 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8498 return NULL;
8499 if (howMany < 0)
8500 return PyErr_Format(PyExc_ValueError,
8501 "negative argument not allowed");
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008502
Victor Stinnerd6f85422010-05-05 23:33:33 +00008503 /* Allocate bytes */
8504 result = PyString_FromStringAndSize(NULL, howMany);
8505 if (result != NULL) {
8506 /* Get random data */
8507 if (RAND_pseudo_bytes((unsigned char*)
8508 PyString_AS_STRING(result),
8509 howMany) < 0) {
8510 Py_DECREF(result);
8511 return PyErr_Format(PyExc_ValueError,
8512 "RAND_pseudo_bytes");
8513 }
8514 }
8515 return result;
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008516}
8517#endif
8518
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008519#ifdef HAVE_SETRESUID
8520PyDoc_STRVAR(posix_setresuid__doc__,
8521"setresuid(ruid, euid, suid)\n\n\
8522Set the current process's real, effective, and saved user ids.");
8523
8524static PyObject*
8525posix_setresuid (PyObject *self, PyObject *args)
8526{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008527 /* We assume uid_t is no larger than a long. */
8528 long ruid, euid, suid;
8529 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
8530 return NULL;
8531 if (setresuid(ruid, euid, suid) < 0)
8532 return posix_error();
8533 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008534}
8535#endif
8536
8537#ifdef HAVE_SETRESGID
8538PyDoc_STRVAR(posix_setresgid__doc__,
8539"setresgid(rgid, egid, sgid)\n\n\
8540Set the current process's real, effective, and saved group ids.");
8541
8542static PyObject*
8543posix_setresgid (PyObject *self, PyObject *args)
8544{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008545 /* We assume uid_t is no larger than a long. */
8546 long rgid, egid, sgid;
8547 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
8548 return NULL;
8549 if (setresgid(rgid, egid, sgid) < 0)
8550 return posix_error();
8551 Py_RETURN_NONE;
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008552}
8553#endif
8554
8555#ifdef HAVE_GETRESUID
8556PyDoc_STRVAR(posix_getresuid__doc__,
8557"getresuid() -> (ruid, euid, suid)\n\n\
8558Get tuple of the current process's real, effective, and saved user ids.");
8559
8560static PyObject*
8561posix_getresuid (PyObject *self, PyObject *noargs)
8562{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008563 uid_t ruid, euid, suid;
8564 long l_ruid, l_euid, l_suid;
8565 if (getresuid(&ruid, &euid, &suid) < 0)
8566 return posix_error();
8567 /* Force the values into long's as we don't know the size of uid_t. */
8568 l_ruid = ruid;
8569 l_euid = euid;
8570 l_suid = suid;
8571 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008572}
8573#endif
8574
8575#ifdef HAVE_GETRESGID
8576PyDoc_STRVAR(posix_getresgid__doc__,
8577"getresgid() -> (rgid, egid, sgid)\n\n\
8578Get tuple of the current process's real, effective, and saved user ids.");
8579
8580static PyObject*
8581posix_getresgid (PyObject *self, PyObject *noargs)
8582{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008583 uid_t rgid, egid, sgid;
8584 long l_rgid, l_egid, l_sgid;
8585 if (getresgid(&rgid, &egid, &sgid) < 0)
8586 return posix_error();
8587 /* Force the values into long's as we don't know the size of uid_t. */
8588 l_rgid = rgid;
8589 l_egid = egid;
8590 l_sgid = sgid;
8591 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008592}
8593#endif
8594
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008595static PyMethodDef posix_methods[] = {
Victor Stinnerd6f85422010-05-05 23:33:33 +00008596 {"access", posix_access, METH_VARARGS, posix_access__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008597#ifdef HAVE_TTYNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008598 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008599#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008600 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008601#ifdef HAVE_CHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008602 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008603#endif /* HAVE_CHFLAGS */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008604 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008605#ifdef HAVE_FCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008606 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008607#endif /* HAVE_FCHMOD */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008608#ifdef HAVE_CHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008609 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008610#endif /* HAVE_CHOWN */
Christian Heimes36281872007-11-30 21:11:28 +00008611#ifdef HAVE_LCHMOD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008612 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008613#endif /* HAVE_LCHMOD */
8614#ifdef HAVE_FCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008615 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
Christian Heimes36281872007-11-30 21:11:28 +00008616#endif /* HAVE_FCHOWN */
Martin v. Löwis382abef2007-02-19 10:55:19 +00008617#ifdef HAVE_LCHFLAGS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008618 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
Martin v. Löwis382abef2007-02-19 10:55:19 +00008619#endif /* HAVE_LCHFLAGS */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008620#ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008621 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00008622#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00008623#ifdef HAVE_CHROOT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008624 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
Martin v. Löwis244edc82001-10-04 22:44:26 +00008625#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008626#ifdef HAVE_CTERMID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008627 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008628#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00008629#ifdef HAVE_GETCWD
Victor Stinnerd6f85422010-05-05 23:33:33 +00008630 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00008631#ifdef Py_USING_UNICODE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008632 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00008633#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00008634#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00008635#ifdef HAVE_LINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008636 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008637#endif /* HAVE_LINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008638 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8639 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8640 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008641#ifdef HAVE_NICE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008642 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008643#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008644#ifdef HAVE_READLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008645 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008646#endif /* HAVE_READLINK */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008647 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8648 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8649 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8650 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008651#ifdef HAVE_SYMLINK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008652 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008653#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008654#ifdef HAVE_SYSTEM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008655 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008656#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008657 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008658#ifdef HAVE_UNAME
Victor Stinnerd6f85422010-05-05 23:33:33 +00008659 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008660#endif /* HAVE_UNAME */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008661 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8662 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8663 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008664#ifdef HAVE_TIMES
Victor Stinnerd6f85422010-05-05 23:33:33 +00008665 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008666#endif /* HAVE_TIMES */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008667 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008668#ifdef HAVE_EXECV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008669 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8670 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008671#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008672#ifdef HAVE_SPAWNV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008673 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8674 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008675#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008676 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8677 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008678#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008679#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008680#ifdef HAVE_FORK1
Victor Stinnerd6f85422010-05-05 23:33:33 +00008681 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008682#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008683#ifdef HAVE_FORK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008684 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008685#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008686#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008687 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008688#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008689#ifdef HAVE_FORKPTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00008690 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008691#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008692#ifdef HAVE_GETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008693 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008694#endif /* HAVE_GETEGID */
8695#ifdef HAVE_GETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008696 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008697#endif /* HAVE_GETEUID */
8698#ifdef HAVE_GETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008699 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008700#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008701#ifdef HAVE_GETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008702 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008703#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008704 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008705#ifdef HAVE_GETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008706 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008707#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008708#ifdef HAVE_GETPPID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008709 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008710#endif /* HAVE_GETPPID */
8711#ifdef HAVE_GETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008712 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008713#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008714#ifdef HAVE_GETLOGIN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008715 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008716#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008717#ifdef HAVE_KILL
Victor Stinnerd6f85422010-05-05 23:33:33 +00008718 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008719#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008720#ifdef HAVE_KILLPG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008721 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008722#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008723#ifdef HAVE_PLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008724 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008725#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008726#ifdef HAVE_POPEN
Victor Stinnerd6f85422010-05-05 23:33:33 +00008727 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008728#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008729 {"popen2", win32_popen2, METH_VARARGS},
8730 {"popen3", win32_popen3, METH_VARARGS},
8731 {"popen4", win32_popen4, METH_VARARGS},
8732 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8733 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008734#else
8735#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008736 {"popen2", os2emx_popen2, METH_VARARGS},
8737 {"popen3", os2emx_popen3, METH_VARARGS},
8738 {"popen4", os2emx_popen4, METH_VARARGS},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008739#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008740#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008741#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008742#ifdef HAVE_SETUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008743 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008744#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008745#ifdef HAVE_SETEUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008746 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008747#endif /* HAVE_SETEUID */
8748#ifdef HAVE_SETEGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008749 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008750#endif /* HAVE_SETEGID */
8751#ifdef HAVE_SETREUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008752 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008753#endif /* HAVE_SETREUID */
8754#ifdef HAVE_SETREGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008755 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008756#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008757#ifdef HAVE_SETGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008758 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008759#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008760#ifdef HAVE_SETGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008761 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008762#endif /* HAVE_SETGROUPS */
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008763#ifdef HAVE_INITGROUPS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008764 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitrou30b3b352009-12-02 20:37:54 +00008765#endif /* HAVE_INITGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008766#ifdef HAVE_GETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008767 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
Martin v. Löwis606edc12002-06-13 21:09:11 +00008768#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008769#ifdef HAVE_SETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008770 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008771#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008772#ifdef HAVE_WAIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00008773 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008774#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008775#ifdef HAVE_WAIT3
Victor Stinnerd6f85422010-05-05 23:33:33 +00008776 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008777#endif /* HAVE_WAIT3 */
8778#ifdef HAVE_WAIT4
Victor Stinnerd6f85422010-05-05 23:33:33 +00008779 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
Neal Norwitz05a45592006-03-20 06:30:08 +00008780#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008781#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008782 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008783#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008784#ifdef HAVE_GETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008785 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008786#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008787#ifdef HAVE_SETSID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008788 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008789#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008790#ifdef HAVE_SETPGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008791 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008792#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008793#ifdef HAVE_TCGETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008794 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008795#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008796#ifdef HAVE_TCSETPGRP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008797 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008798#endif /* HAVE_TCSETPGRP */
Victor Stinnerd6f85422010-05-05 23:33:33 +00008799 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8800 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8801 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8802 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8803 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8804 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8805 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8806 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8807 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8808 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8809 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008810#ifdef HAVE_PIPE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008811 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008812#endif
8813#ifdef HAVE_MKFIFO
Victor Stinnerd6f85422010-05-05 23:33:33 +00008814 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008815#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008816#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008817 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008818#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008819#ifdef HAVE_DEVICE_MACROS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008820 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8821 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8822 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008823#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008824#ifdef HAVE_FTRUNCATE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008825 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008826#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008827#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008828 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008829#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008830#ifdef HAVE_UNSETENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00008831 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
Guido van Rossumc524d952001-10-19 01:31:59 +00008832#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008833 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008834#ifdef HAVE_FCHDIR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008835 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
Fred Drake4d1e64b2002-04-15 19:40:07 +00008836#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008837#ifdef HAVE_FSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008838 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008839#endif
8840#ifdef HAVE_FDATASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00008841 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008842#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008843#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008844#ifdef WCOREDUMP
Victor Stinnerd6f85422010-05-05 23:33:33 +00008845 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
Fred Drake106c1a02002-04-23 15:58:02 +00008846#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008847#ifdef WIFCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008848 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008849#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008850#ifdef WIFSTOPPED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008851 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008852#endif /* WIFSTOPPED */
8853#ifdef WIFSIGNALED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008854 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008855#endif /* WIFSIGNALED */
8856#ifdef WIFEXITED
Victor Stinnerd6f85422010-05-05 23:33:33 +00008857 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008858#endif /* WIFEXITED */
8859#ifdef WEXITSTATUS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008860 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008861#endif /* WEXITSTATUS */
8862#ifdef WTERMSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008863 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008864#endif /* WTERMSIG */
8865#ifdef WSTOPSIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008866 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008867#endif /* WSTOPSIG */
8868#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008869#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008870 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008871#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008872#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Victor Stinnerd6f85422010-05-05 23:33:33 +00008873 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008874#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008875#ifdef HAVE_TMPFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00008876 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008877#endif
8878#ifdef HAVE_TEMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008879 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008880#endif
8881#ifdef HAVE_TMPNAM
Victor Stinnerd6f85422010-05-05 23:33:33 +00008882 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008883#endif
Fred Drakec9680921999-12-13 16:37:25 +00008884#ifdef HAVE_CONFSTR
Victor Stinnerd6f85422010-05-05 23:33:33 +00008885 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008886#endif
8887#ifdef HAVE_SYSCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008888 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008889#endif
8890#ifdef HAVE_FPATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008891 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008892#endif
8893#ifdef HAVE_PATHCONF
Victor Stinnerd6f85422010-05-05 23:33:33 +00008894 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008895#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00008896 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008897#ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008898 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Mark Hammondef8b6542001-05-13 08:04:26 +00008899#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008900#ifdef HAVE_GETLOADAVG
Victor Stinnerd6f85422010-05-05 23:33:33 +00008901 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008902#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008903 #ifdef MS_WINDOWS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008904 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008905 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008906 #ifdef __VMS
Victor Stinnerd6f85422010-05-05 23:33:33 +00008907 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008908 #endif
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008909#ifdef HAVE_SETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008910 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008911#endif
8912#ifdef HAVE_SETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008913 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008914#endif
8915#ifdef HAVE_GETRESUID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008916 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008917#endif
8918#ifdef HAVE_GETRESGID
Victor Stinnerd6f85422010-05-05 23:33:33 +00008919 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
Martin v. Löwis50ea4562009-11-27 13:56:01 +00008920#endif
8921
Victor Stinnerd6f85422010-05-05 23:33:33 +00008922 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008923};
8924
8925
Barry Warsaw4a342091996-12-19 23:50:02 +00008926static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008927ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008928{
Victor Stinnerd6f85422010-05-05 23:33:33 +00008929 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008930}
8931
Guido van Rossumd48f2521997-12-05 22:19:34 +00008932#if defined(PYOS_OS2)
8933/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008934static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008935{
8936 APIRET rc;
8937 ULONG values[QSV_MAX+1];
8938 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008939 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008940
8941 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008942 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008943 Py_END_ALLOW_THREADS
8944
8945 if (rc != NO_ERROR) {
8946 os2_error(rc);
8947 return -1;
8948 }
8949
Fred Drake4d1e64b2002-04-15 19:40:07 +00008950 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8951 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8952 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8953 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8954 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8955 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8956 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008957
8958 switch (values[QSV_VERSION_MINOR]) {
8959 case 0: ver = "2.00"; break;
8960 case 10: ver = "2.10"; break;
8961 case 11: ver = "2.11"; break;
8962 case 30: ver = "3.00"; break;
8963 case 40: ver = "4.00"; break;
8964 case 50: ver = "5.00"; break;
8965 default:
Tim Peters885d4572001-11-28 20:27:42 +00008966 PyOS_snprintf(tmp, sizeof(tmp),
Victor Stinnerd6f85422010-05-05 23:33:33 +00008967 "%d-%d", values[QSV_VERSION_MAJOR],
Tim Peters885d4572001-11-28 20:27:42 +00008968 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008969 ver = &tmp[0];
8970 }
8971
8972 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008973 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008974 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008975
8976 /* Add Indicator of Which Drive was Used to Boot the System */
8977 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8978 tmp[1] = ':';
8979 tmp[2] = '\0';
8980
Fred Drake4d1e64b2002-04-15 19:40:07 +00008981 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008982}
8983#endif
8984
Barry Warsaw4a342091996-12-19 23:50:02 +00008985static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008986all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008987{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008988#ifdef F_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008989 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008990#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008991#ifdef R_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008992 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008993#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008994#ifdef W_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008995 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008996#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008997#ifdef X_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00008998 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008999#endif
Fred Drakec9680921999-12-13 16:37:25 +00009000#ifdef NGROUPS_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009001 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +00009002#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009003#ifdef TMP_MAX
Victor Stinnerd6f85422010-05-05 23:33:33 +00009004 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00009005#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009006#ifdef WCONTINUED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009007 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009008#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009009#ifdef WNOHANG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009010 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009011#endif
Fred Drake106c1a02002-04-23 15:58:02 +00009012#ifdef WUNTRACED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009013 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +00009014#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00009015#ifdef O_RDONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009016 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009017#endif
9018#ifdef O_WRONLY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009019 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009020#endif
9021#ifdef O_RDWR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009022 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009023#endif
9024#ifdef O_NDELAY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009025 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009026#endif
9027#ifdef O_NONBLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009028 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009029#endif
9030#ifdef O_APPEND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009031 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009032#endif
9033#ifdef O_DSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009034 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009035#endif
9036#ifdef O_RSYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009037 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009038#endif
9039#ifdef O_SYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009040 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009041#endif
9042#ifdef O_NOCTTY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009043 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009044#endif
9045#ifdef O_CREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009046 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009047#endif
9048#ifdef O_EXCL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009049 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009050#endif
9051#ifdef O_TRUNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009052 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +00009053#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00009054#ifdef O_BINARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009055 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009056#endif
9057#ifdef O_TEXT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009058 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +00009059#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009060#ifdef O_LARGEFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009061 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009062#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00009063#ifdef O_SHLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009064 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009065#endif
9066#ifdef O_EXLOCK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009067 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +00009068#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009069
Tim Peters5aa91602002-01-30 05:46:57 +00009070/* MS Windows */
9071#ifdef O_NOINHERIT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009072 /* Don't inherit in child processes. */
9073 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009074#endif
9075#ifdef _O_SHORT_LIVED
Victor Stinnerd6f85422010-05-05 23:33:33 +00009076 /* Optimize for short life (keep in memory). */
9077 /* MS forgot to define this one with a non-underscore form too. */
9078 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009079#endif
9080#ifdef O_TEMPORARY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009081 /* Automatically delete when last handle is closed. */
9082 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009083#endif
9084#ifdef O_RANDOM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009085 /* Optimize for random access. */
9086 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009087#endif
9088#ifdef O_SEQUENTIAL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009089 /* Optimize for sequential access. */
9090 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00009091#endif
9092
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009093/* GNU extensions. */
Georg Brandl5049a852008-05-16 13:10:15 +00009094#ifdef O_ASYNC
Victor Stinnerd6f85422010-05-05 23:33:33 +00009095 /* Send a SIGIO signal whenever input or output
9096 becomes available on file descriptor */
9097 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +00009098#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009099#ifdef O_DIRECT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009100 /* Direct disk access. */
9101 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009102#endif
9103#ifdef O_DIRECTORY
Victor Stinnerd6f85422010-05-05 23:33:33 +00009104 /* Must be a directory. */
9105 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009106#endif
9107#ifdef O_NOFOLLOW
Victor Stinnerd6f85422010-05-05 23:33:33 +00009108 /* Do not follow links. */
9109 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00009110#endif
Georg Brandlb67da6e2007-11-24 13:56:09 +00009111#ifdef O_NOATIME
Victor Stinnerd6f85422010-05-05 23:33:33 +00009112 /* Do not update the access time. */
9113 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
Georg Brandlb67da6e2007-11-24 13:56:09 +00009114#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00009115
Victor Stinnerd6f85422010-05-05 23:33:33 +00009116 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009117#ifdef EX_OK
Victor Stinnerd6f85422010-05-05 23:33:33 +00009118 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009119#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009120#ifdef EX_USAGE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009121 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009122#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009123#ifdef EX_DATAERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009124 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009125#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009126#ifdef EX_NOINPUT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009127 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009128#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009129#ifdef EX_NOUSER
Victor Stinnerd6f85422010-05-05 23:33:33 +00009130 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009131#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009132#ifdef EX_NOHOST
Victor Stinnerd6f85422010-05-05 23:33:33 +00009133 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009134#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009135#ifdef EX_UNAVAILABLE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009136 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009137#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009138#ifdef EX_SOFTWARE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009139 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009140#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009141#ifdef EX_OSERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009142 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009143#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009144#ifdef EX_OSFILE
Victor Stinnerd6f85422010-05-05 23:33:33 +00009145 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009146#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009147#ifdef EX_CANTCREAT
Victor Stinnerd6f85422010-05-05 23:33:33 +00009148 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009149#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009150#ifdef EX_IOERR
Victor Stinnerd6f85422010-05-05 23:33:33 +00009151 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009152#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009153#ifdef EX_TEMPFAIL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009154 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009155#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009156#ifdef EX_PROTOCOL
Victor Stinnerd6f85422010-05-05 23:33:33 +00009157 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009158#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009159#ifdef EX_NOPERM
Victor Stinnerd6f85422010-05-05 23:33:33 +00009160 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009161#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009162#ifdef EX_CONFIG
Victor Stinnerd6f85422010-05-05 23:33:33 +00009163 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009164#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009165#ifdef EX_NOTFOUND
Victor Stinnerd6f85422010-05-05 23:33:33 +00009166 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00009167#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00009168
Guido van Rossum246bc171999-02-01 23:54:31 +00009169#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009170#if defined(PYOS_OS2) && defined(PYCC_GCC)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009171 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
9172 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
9173 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
9174 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
9175 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
9176 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
9177 if (ins(d, "P_PM", (long)P_PM)) return -1;
9178 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
9179 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
9180 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
9181 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
9182 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
9183 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
9184 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
9185 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
9186 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
9187 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
9188 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
9189 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
9190 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009191#else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009192 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
9193 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
9194 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
9195 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
9196 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00009197#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009198#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00009199
Guido van Rossumd48f2521997-12-05 22:19:34 +00009200#if defined(PYOS_OS2)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009201 if (insertvalues(d)) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00009202#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009203 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +00009204}
9205
9206
Tim Peters5aa91602002-01-30 05:46:57 +00009207#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009208#define INITFUNC initnt
9209#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009210
9211#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009212#define INITFUNC initos2
9213#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00009214
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00009215#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00009216#define INITFUNC initposix
9217#define MODNAME "posix"
9218#endif
9219
Mark Hammondfe51c6d2002-08-02 02:27:13 +00009220PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00009221INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00009222{
Victor Stinnerd6f85422010-05-05 23:33:33 +00009223 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00009224
Victor Stinnerd6f85422010-05-05 23:33:33 +00009225 m = Py_InitModule3(MODNAME,
9226 posix_methods,
9227 posix__doc__);
9228 if (m == NULL)
9229 return;
Tim Peters5aa91602002-01-30 05:46:57 +00009230
Victor Stinnerd6f85422010-05-05 23:33:33 +00009231 /* Initialize environ dictionary */
9232 v = convertenviron();
9233 Py_XINCREF(v);
9234 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
9235 return;
9236 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00009237
Victor Stinnerd6f85422010-05-05 23:33:33 +00009238 if (all_ins(m))
9239 return;
Barry Warsaw4a342091996-12-19 23:50:02 +00009240
Victor Stinnerd6f85422010-05-05 23:33:33 +00009241 if (setup_confname_tables(m))
9242 return;
Fred Drakebec628d1999-12-15 18:31:10 +00009243
Victor Stinnerd6f85422010-05-05 23:33:33 +00009244 Py_INCREF(PyExc_OSError);
9245 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00009246
Guido van Rossumb3d39562000-01-31 18:41:26 +00009247#ifdef HAVE_PUTENV
Victor Stinnerd6f85422010-05-05 23:33:33 +00009248 if (posix_putenv_garbage == NULL)
9249 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00009250#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009251
Victor Stinnerd6f85422010-05-05 23:33:33 +00009252 if (!initialized) {
9253 stat_result_desc.name = MODNAME ".stat_result";
9254 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
9255 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
9256 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
9257 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
9258 structseq_new = StatResultType.tp_new;
9259 StatResultType.tp_new = statresult_new;
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00009260
Victor Stinnerd6f85422010-05-05 23:33:33 +00009261 statvfs_result_desc.name = MODNAME ".statvfs_result";
9262 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009263#ifdef NEED_TICKS_PER_SECOND
9264# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009265 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis03824e42008-12-29 18:17:34 +00009266# elif defined(HZ)
Victor Stinnerd6f85422010-05-05 23:33:33 +00009267 ticks_per_second = HZ;
Martin v. Löwis03824e42008-12-29 18:17:34 +00009268# else
Victor Stinnerd6f85422010-05-05 23:33:33 +00009269 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis03824e42008-12-29 18:17:34 +00009270# endif
9271#endif
Victor Stinnerd6f85422010-05-05 23:33:33 +00009272 }
9273 Py_INCREF((PyObject*) &StatResultType);
9274 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
9275 Py_INCREF((PyObject*) &StatVFSResultType);
9276 PyModule_AddObject(m, "statvfs_result",
9277 (PyObject*) &StatVFSResultType);
9278 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009279
9280#ifdef __APPLE__
Victor Stinnerd6f85422010-05-05 23:33:33 +00009281 /*
9282 * Step 2 of weak-linking support on Mac OS X.
9283 *
9284 * The code below removes functions that are not available on the
9285 * currently active platform.
9286 *
9287 * This block allow one to use a python binary that was build on
9288 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
9289 * OSX 10.4.
9290 */
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009291#ifdef HAVE_FSTATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009292 if (fstatvfs == NULL) {
9293 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
9294 return;
9295 }
9296 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009297#endif /* HAVE_FSTATVFS */
9298
9299#ifdef HAVE_STATVFS
Victor Stinnerd6f85422010-05-05 23:33:33 +00009300 if (statvfs == NULL) {
9301 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9302 return;
9303 }
9304 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009305#endif /* HAVE_STATVFS */
9306
9307# ifdef HAVE_LCHOWN
Victor Stinnerd6f85422010-05-05 23:33:33 +00009308 if (lchown == NULL) {
9309 if (PyObject_DelAttrString(m, "lchown") == -1) {
9310 return;
9311 }
9312 }
Ronald Oussorend06b6f22006-04-23 11:59:25 +00009313#endif /* HAVE_LCHOWN */
9314
9315
9316#endif /* __APPLE__ */
9317
Guido van Rossumb6775db1994-08-01 11:34:53 +00009318}
Anthony Baxterac6bd462006-04-13 02:06:09 +00009319
9320#ifdef __cplusplus
9321}
9322#endif
9323
Martin v. Löwis18aaa562006-10-15 08:43:33 +00009324